PyQt5 线程、信号和插槽。连接错误
Posted
技术标签:
【中文标题】PyQt5 线程、信号和插槽。连接错误【英文标题】:PyQt5 Threads, Signal, and Slot. Connect Error 【发布时间】:2021-01-27 10:27:49 【问题描述】:我是 PyQt5 的新手,我似乎无法连接我的 pyqtSignal 和 pyqtSlot。错误,"TypeError: connect() failed between worker.newIcon[object] and updateIcon()" 弹出。任何人都可以指导我正确的道路吗?
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()
【问题讨论】:
请不要使用外部网站共享代码,而是将其嵌入您的问题中(阅读如何正确地format your code 并在保存更改之前检查预览中的语法和缩进)。 我正在研究答案:您真的需要两个不同的线程并将它们连接在一起吗?您使用此应用程序的目标是什么? 本例中的工作线程只是实现定时器的一种过于复杂的方式。此外,由于 QIcon 是基于像素图的,它似乎不是线程安全的。使用 QTimer 的解决方案会更简单、更安全、更高效。 【参考方案1】:pyqtSlot
装饰器旨在用于QObject
子类,否则将无法正常工作。
所以,解决方案很简单,你只需要从 QObject 继承:
class systemTray(QObject):
def start_tray(self):
# ...
另一方面,很少需要使用 pyqtSlot
装饰器,并且仅用于特定情况(请参阅this related answer。在您的情况下,似乎没有必要。
此外,由于您已经从 QThread 继承,您可以只使用它自己的 start()
,而无需在新的 moveToThread()
上使用。
【讨论】:
以上是关于PyQt5 线程、信号和插槽。连接错误的主要内容,如果未能解决你的问题,请参考以下文章
Qt 4.8:来自不同线程的两个信号和一个插槽之间的连接行为