Python PyQt4 信号未触发连接方法

Posted

技术标签:

【中文标题】Python PyQt4 信号未触发连接方法【英文标题】:Python PyQt4 signal not firing connected method 【发布时间】:2013-10-07 04:27:08 【问题描述】:

我决定使用信号来指示线程的完成。如果仍然存在更多工作,我将信号连接到重新启动过程的代码。唉,连接到信号的代码永远不会触发。这让我很难过。

我需要知道为什么下面代码块中的方法“Tester”没有触发。

我是 python 新手,所以当我开始写这篇文章时,我研究了信号并在 tgray 发布 here 的解决方案之后建模了代码,显然我错过了一些重要的东西,但我真的看不出它是什么是。

这是我的代码的大规模简化版本:

from PyQt4.QtCore import *
import time

class Worker(QThread):
    __pyqtSignals__ = ( "a", 
                        "b" )
    def __init__(self):
        QThread.__init__(self, None)


    def run(self):
        print "'Worker.run' starts"
        self.emit(SIGNAL("a"))
        print "'Worker.run' ends"


class Main:
    def Do(self):
        print "'Do' starts"
        self.Launch()
        time.sleep(2)
        print "'Do' ends"


    def Launch(self):
        print "'Launch' starts"
        self.worker = Worker()
        QObject.connect(self.worker, SIGNAL("a"), self.Tester)
        self.worker.daemon = True
        self.worker.start()
        print "'Launch' ends"


    def Tester(self):
        print "Tester Fired!!"

m=Main()

跑步:

>>> m.Do()

产量:

'Do' starts
'Launch' starts
'Launch' ends
'Do' ends
'Worker.run' starts
'Worker.run' ends

但不是预期的:

Tester Fired!!

我错过了什么?另外,为什么即使使用sleep(2),“Worker.run”中的打印也会出现在其他所有内容之后?

【问题讨论】:

请注意,您可以使用new-style signal and slots:self.worker.a.connect(self.Tester),而不是使用QObject.connect(...)。这有很多优点:更容易阅读,更短,更安全,因为如果a 信号不存在,则会引发错误,而使用其他方法连接将无声无息地失败。 好点!一旦我得到这个版本的功能,我将重构以实现新样式的 s&s。谢谢! 【参考方案1】:

如果你想看到你的回调被调用,你必须改变你的连接方式 您的 QThread 信号到您的插槽:

 QtCore.QObject.connect(self.worker,
                        Qt.SIGNAL("a"),
                        self.Tester,
                        Qt.Qt.DirectConnection) #this is added

解释: 自 Qt 4 以来,Qt 信号/插槽是线程安全的。文档说明了正常行为时 将信号连接到插槽是“AutoConnection”,这意味着它是直接的(回调是 在发出后立即触发)如果信号和槽都在同一个线程中,而它 如果信号是从另一个线程(您的情况)发出的,则排队。

然后,必须处理这个队列:通常,这是在您的应用程序运行时由 Qt 循环完成的。

信号“排队”这一事实意味着控制权被转移到 Qt 循环中,以使 确保在主线程中调用回调,即使信号来自另一个 线程。

在您的问题代码中,根本没有事件循环 - 所以获取您的问题的唯一方法 从另一个线程调用的槽是为了改变信号的调度方式。不要使用 但是,在您的代码中,因为在普通应用程序中您运行 Qt 循环, 它会被正确地发送(并且安全地避免线程问题)。

【讨论】:

感谢您的回复!是的,我现在看到我的实现存在根本缺陷(没有 QT 循环,叹息)。我希望在 Python、PySide 和 PyGame 上投入足够的实践和学习时间,以达到专业程序员级别的机制理解。然后我可以帮助别人并创建好的代码。我发现关于此类事情的 python 信息分为两组:非常基本的示例,或者假设对基本框架有深入了解的高级用户文档。所以我试图在中间地带艰难前行,直到我达到关于该主题的“临界质量”知识。再次感谢!

以上是关于Python PyQt4 信号未触发连接方法的主要内容,如果未能解决你的问题,请参考以下文章

PyQt4 信号和 QObject.Emit()

pyqt4正确连接QCheckbox状态

PyQt4发射信号

QML - .qml 文件中的“连接”不会触发来自 python 脚本的信号

PyQt4.QtCore.pyqtSignal 对象没有属性“连接”

使用 pyqt4 创建类信号