简体   繁体   中英

PyQt5 Threads, Signal, and Slot. Connect Error

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()

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():
    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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM