Reputation: 17
I'm new to PyQt5 and I can't seem to connect my pyqtSignal and pyqtSlot. The error, "TypeError: connect() failed between worker.newIcon[object] and updateIcon()" pops out. Anyone can guide me to the right path please?
from PyQt5.QtWidgets import QApplication, QSystemTrayIcon, QAction, QMenu
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QObject, QThread, pyqtSignal, pyqtSlot
class worker(QThread):
newIcon = pyqtSignal(object)
def run(self):
while True:
self.newIcon.emit(QIcon("shield-off.png"))
QThread.msleep(1000)
class systemTray():
def start_tray(self):
self.app = QApplication([])
self.app.setQuitOnLastWindowClosed(False)
icon = QIcon("shield-on.png")
self.tray = QSystemTrayIcon()
self.tray.setIcon(icon)
self.tray.setVisible(True)
self.menu = QMenu()
self.quit = QAction("Exit")
self.quit.triggered.connect(self.app.quit)
self.menu.addAction(self.quit)
self.tray.setContextMenu(self.menu)
self.thread = QThread()
self.worker = worker()
self.worker.moveToThread(self.thread)
self.worker.newIcon.connect(self.updateIcon)
self.thread.started.connect(self.worker.run)
self.thread.start()
# Run tray
self.app.exec_()
@pyqtSlot(object)
def updateIcon(self, icon):
self.tray.setIcon(icon)
if __name__ == "__main__":
be_tray = systemTray()
be_tray.start_tray()
Upvotes: 1
Views: 664
Reputation: 48241
The pyqtSlot
decorator is intended to be used for QObject
subclasses, otherwise it will not work correctly.
So, the solution is pretty simple, as you only need to inherit from QObject:
class systemTray(QObject):
def start_tray(self):
# ...
On the other hand, using a pyqtSlot
decorator is rarely needed and only for specific situations (see this related answer. In your case, it doesn't seem necessary.
Also, since you're already subclassing from QThread, you can just use its own start()
, without using moveToThread()
on a new one.
Upvotes: 3