PySide6: Issues with signals and Threads
-
Hey,
first of all: I read this:
https://doc.qt.io/qt-6/qthread.html#QThreadWhat I want to achieve:
I established a socket connection and pass data between my PC and a controller unit.
This works. Until now everything was running in the same thread.
In my service class i created a new QThread instance and a worker instance, connected some signals with slots and moved the worker to the new thread before calling start:class service(QObject): start_worker = Signal() stop_worker = Signal() transmit_data = Signal(str) def __init__(self, ip:str, port:int, parent=None): super().__init__(parent) self.ip = ip self.port = port self.worker = None self.ready_to_send :bool = False @Slot() def start(self): self.worker = socketworker(ip=self.ip, port=self.port) self.transmit_data.connect(self.worker.handle_transmit) self.start_worker.connect(self.worker.work) self.worker.started.connect(self.handle_started) self.worker.stopped.connect(self.handle_stopped) self.worker.connected.connect(self.handle_connection) self.worker.data.connect(self.handle_data) self.worker.notconnected.connect(self.handle_notconnected) self.worker.ready.connect(self.handle_ready) self.workerthread = QThread() self.worker.moveToThread(self.workerthread) self.workerthread.start() self.start_worker.emit()
worker-class:
class socketworker(QObject): started = Signal(bool, str) stopped = Signal(bool) connected = Signal(str, str) notconnected = Signal(str) data = Signal(str) ready = Signal(bool) def __init__(self, ip:str, port:int, parent = None): super().__init__(parent) self.ip = ip self.port = port self.server = None self.is_running = False self.data_to_transmit = None self.start_transmit = False self.transmitting = False self.buffersize = 1024 self.robostatus = message() def work(self): try: self.is_running = True self.started.emit(True, "") except Exception as e: self.started.emit(False, str(e)) with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: #s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1) s.bind((self.ip, self.port)) self.connected.emit("socketserver", "bound") while self.is_running: self.connected.emit("socketserver", "listening") s.listen() conn, addr = s.accept() self.connected.emit("scketserver", "connected") with conn: self.connected.emit(str(conn), str(addr)) while conn.fileno() != -1: self.receive(conn) self.send(conn) self.connected.emit("socketserver: ", "connection lost, socket closed")
I test the module like this:
if __name__ == "__main__": import time app = QApplication(sys.argv) sockservice = service(ip="0.0.0.0" , port=9999) sockservice.start() sentall = False orders = ["Befehl", "Ich mag Toastbrot", "mit Marmelade", "dazu Orangensaft" ] i = 0 while not sentall: if sockservice.ready_to_send: sockservice.transmit_data.emit(orders[i]) time.sleep(1) i +=1 if i>3: print("DONE!!!!") break sockservice.stop() sys.exit(app.exec())
When i execute this, I can connect the controller to my PC and exchange data. Everything is fine except that the handlers are never called (actually they have nothing more than a print statement).
What is wrong here?!?
Sideinfo:
Pyside6 is latest version -
-
Hey,
first of all: I read this:
https://doc.qt.io/qt-6/qthread.html#QThreadWhat I want to achieve:
I established a socket connection and pass data between my PC and a controller unit.
This works. Until now everything was running in the same thread.
In my service class i created a new QThread instance and a worker instance, connected some signals with slots and moved the worker to the new thread before calling start:class service(QObject): start_worker = Signal() stop_worker = Signal() transmit_data = Signal(str) def __init__(self, ip:str, port:int, parent=None): super().__init__(parent) self.ip = ip self.port = port self.worker = None self.ready_to_send :bool = False @Slot() def start(self): self.worker = socketworker(ip=self.ip, port=self.port) self.transmit_data.connect(self.worker.handle_transmit) self.start_worker.connect(self.worker.work) self.worker.started.connect(self.handle_started) self.worker.stopped.connect(self.handle_stopped) self.worker.connected.connect(self.handle_connection) self.worker.data.connect(self.handle_data) self.worker.notconnected.connect(self.handle_notconnected) self.worker.ready.connect(self.handle_ready) self.workerthread = QThread() self.worker.moveToThread(self.workerthread) self.workerthread.start() self.start_worker.emit()
worker-class:
class socketworker(QObject): started = Signal(bool, str) stopped = Signal(bool) connected = Signal(str, str) notconnected = Signal(str) data = Signal(str) ready = Signal(bool) def __init__(self, ip:str, port:int, parent = None): super().__init__(parent) self.ip = ip self.port = port self.server = None self.is_running = False self.data_to_transmit = None self.start_transmit = False self.transmitting = False self.buffersize = 1024 self.robostatus = message() def work(self): try: self.is_running = True self.started.emit(True, "") except Exception as e: self.started.emit(False, str(e)) with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: #s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1) s.bind((self.ip, self.port)) self.connected.emit("socketserver", "bound") while self.is_running: self.connected.emit("socketserver", "listening") s.listen() conn, addr = s.accept() self.connected.emit("scketserver", "connected") with conn: self.connected.emit(str(conn), str(addr)) while conn.fileno() != -1: self.receive(conn) self.send(conn) self.connected.emit("socketserver: ", "connection lost, socket closed")
I test the module like this:
if __name__ == "__main__": import time app = QApplication(sys.argv) sockservice = service(ip="0.0.0.0" , port=9999) sockservice.start() sentall = False orders = ["Befehl", "Ich mag Toastbrot", "mit Marmelade", "dazu Orangensaft" ] i = 0 while not sentall: if sockservice.ready_to_send: sockservice.transmit_data.emit(orders[i]) time.sleep(1) i +=1 if i>3: print("DONE!!!!") break sockservice.stop() sys.exit(app.exec())
When i execute this, I can connect the controller to my PC and exchange data. Everything is fine except that the handlers are never called (actually they have nothing more than a print statement).
What is wrong here?!?
Sideinfo:
Pyside6 is latest versionHi,
Since you marked it as solved, can you explain what you did to fix your original issue ?
From the looks of your code, you are not starting the event loop until after your thread did its work.