【问题标题】:How do I connect a PyQt5 slot to a signal function in a class?如何将 PyQt5 插槽连接到类中的信号函数?
【发布时间】:2016-08-29 16:01:19
【问题描述】:

我正在尝试在 UI 代码块和仅用于处理事件响应的单独 python 类之间设置 pyqt 信号。我不想让 UI 代码访问处理程序(经典 MVC 样式)。不幸的是,我很难将插槽连接到信号。代码如下:

from PyQt5 import QtCore
from PyQt5.QtCore import QObject

class UiClass(QObject):
    mySignal = QtCore.pyqtSignal( str )
    def __init__(self):
        QObject.__init__(self)
    def send_signal(self):
        self.mySignal.emit("Hello world!")

class HandlerClass():
    currentMessage = "none"
    def register(self, mySignal):
        mySignal.connect(self.receive_signal)        
    @QtCore.pyqtSlot(str)
    def receive_signal(self, message):
        self.currentMessage = message
        print(message)

ui = UiClass()
handler = HandlerClass()
handler.register(ui.mySignal)
ui.send_signal()

当我运行此代码时,它在 handler.register 行失败。这是错误:

Traceback(最近一次调用最后一次):

文件“C:\git\IonControl\testpyqtslot.py”,第 25 行,在

handler.register(ui.mySignal)

文件“C:\git\IonControl\testpyqtslot.py”,第 17 行,在寄存器中

mySignal.connect(self.receive_signal)

TypeError: UiClass.mySignal[str] 和 receive_signal() 之间的 connect() 失败

我希望这段代码能够成功地将信号注册到插槽并让处理程序在最后打印“hello world”。我在这里做错了什么?

我的基本问题是:如何将信号连接到属于类的槽函数?

【问题讨论】:

    标签: python-3.x pyqt5


    【解决方案1】:

    发生错误是因为您在不继承自 QObject 的类中使用 pyqtSlot 装饰器。您可以通过去掉装饰器或将HandlerClass 设为QObject 的子类来解决此问题。

    pyqtSlot 的主要目的是允许定义多个不同的插槽重载,每个重载都有不同的签名。有时在进行跨线程连接时也可能需要它。然而,这些用例相对较少,在大多数 PyQt 应用程序中根本不需要使用pyqtSlot。信号可以连接到任何 python 可调用对象,无论它是否被装饰为插槽。

    【讨论】:

    • 我将 HandlerClass 设为 QObject 的子类,它运行良好。谢谢!
    • 什么时候需要跨线程连接?总是?这是否记录在某处?
    • @DavidPärsson。不知道它是否已记录在案,但请参阅 this answer 了解可能需要它的一种情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多