[Python] Waiting for a PyQt/PySide.QtCore.QThread to finish before doing something

Discussão em 'Python' iniciado por Stack, Dezembro 13, 2024.

  1. Stack

    Stack Membro Participativo

    I have a data acquisition thread which samples and processes data which it then emits as a signal to a receiver.

    Now, when that thread is stopped, how can I ensure it has finished the current loop and emitted its signal before proceeding (and e.g. emitting a summary signal)?

    import sys
    import time

    from PySide6.QtCore import Signal, Slot
    from PySide6 import QtCore
    from PySide6 import QtWidgets


    ##==============================================================================
    class EmitterClassThreaded(QtCore.QThread):
    ## Define a signal that emits a dictionary
    data_signal = Signal(dict)

    ##--------------------------------------------------------------------------
    def __init__(self):
    super().__init__()
    self.counter = 0
    self.t_start = time.time()
    self.running = True

    ## Connect the signal to a method within the same class
    self.data_signal.connect(self.handle_data)

    ##--------------------------------------------------------------------------
    def run(self):
    while self.running:
    self.counter += 1
    now = time.time() - self.t_start
    data = {'counter': self.counter, 'timestamp': f"{now:.1f}"}
    time.sleep(1) # <------ doing something here which takes time
    self.data_signal.emit(data)

    ##--------------------------------------------------------------------------
    def stop(self):
    self.running = False

    ##--------------------------------------------------------------------------
    @Slot(dict)
    def handle_data(self, data):
    print(f"EmitterClassThreaded received data: {data}")


    ##==============================================================================
    class ReceiverClass():
    def __init__(self):
    super().__init__()

    ##--------------------------------------------------------------------------
    @Slot(dict)
    def handle_data(self, data):
    print(f"ReceiverClass received data: {data}")


    ##==============================================================================
    class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
    super().__init__()

    self.setWindowTitle("Example ThreadedEmitter-Receiver")
    self.setGeometry(100, 100, 400, 200)

    self.label = QtWidgets.QLabel("Waiting for signal...", self)
    self.label.move(150, 80)

    self.stop_button = QtWidgets.QPushButton("Stop Emitter", self)
    self.stop_button.move(150, 120)
    self.stop_button.clicked.connect(self.stop_emitter)

    self.emitter = EmitterClassThreaded()
    self.emitter.data_signal.connect(self.handle_data)

    self.receiver = ReceiverClass()

    ## Connect the signal from EmitterClass to the method in ReceiverClass
    self.emitter.data_signal.connect(self.receiver.handle_data)

    ## Start the emitter thread
    self.emitter.start()
    self.emitter.running = True

    ##--------------------------------------------------------------------------
    @Slot(dict)
    def handle_data(self, data):
    self.label.setText(f"Counter: {data['counter']}\nTimestamp: {data['timestamp']}")

    ##--------------------------------------------------------------------------
    def stop_emitter(self):
    print("ReceiverClass: Stopping the emitter thread...")
    self.emitter.stop()
    ## TODO: Wait for the thread to finish (incl. emitting the last signal) before proceeding
    print("Creating own data to emit.")
    self.emitter.data_signal.emit({'counter': -999, 'timestamp': 0})

    ##******************************************************************************
    ##******************************************************************************
    if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())


    In my current example, the last signal from the thread always overwrites that summary signal. Thanks in advance!

    Continue reading...

Compartilhe esta Página