Python QT发出信号没有调用回调函数

Posted

技术标签:

【中文标题】Python QT发出信号没有调用回调函数【英文标题】:Python QT emit SIGNAL is not invoking callback function 【发布时间】:2014-01-22 20:52:01 【问题描述】:

我有以下代码:

def callback(param):
    print "in callback"

class Test(QThread):
    def __init__(self):
        QThread.__init__(self)
        #QObject.connect(self, SIGNAL("test_signal(PyQt_PyObject)"), callback)
        print "Test constructed"

    def fallback(self, dummy=None):
        print "in fallback"

    def run(self):
        while 1:
            print "Test running"
            self.emit(SIGNAL("test_signal(PyQt_PyObject)"), 'a': 'b')
            time.sleep(1)

t = None

if __name__ == "__main__":

    t = Test()
    t.start()
    QObject.connect(t, SIGNAL("test_signal(PyQt_PyObject)"), callback)
    while True:
        time.sleep(2)

但是,callback(param) 从未被调用,因为我没有看到控制台上打印的“in callback”。有人能帮忙吗?我尝试了代码的不同变体(例如,从 test_signal 中删除参数,连接到 self.fallback(),不包括 self.emit 中的任何参数(即删除 'a': 'b'))。我一定错过了一个非常简单但基本的机制,但我就是想不通。

提前致谢!

【问题讨论】:

我通常使用 C++ qt,但这看起来并不像使用 pyqt 正确定义和发射信号。检查这个pythoncentral.io/… 【参考方案1】:

如果你想让一个线程使用信号你需要启动一个事件循环,更直接的方法是启动一个QApplication

from PyQt4.QtGui import QApplication
from PyQt4.QtCore import *
import time

@pyqtSlot(dict)
def callback(param):
    print "in callback"
    print param

class Test(QThread):

    mySignal =  pyqtSignal(dict,name="mySignal")

    def __init__(self):
        QThread.__init__(self)

    def run(self):
        while 1:
            print "Test running"
            self.mySignal.emit('a': 'b')
            time.sleep(1)

if __name__ == "__main__":
    t = Test()
    t.start()
    t.mySignal.connect(callback)
    app = QApplication([])
    app.exec_()

【讨论】:

对于那些可能想知道不同信号样式的人,您可以找到更多关于新样式信号的信息here,以及关于旧样式信号的信息here。我发现旧页面上的新旧比较也很有用。 您能否提供一个如何正确使用 Eventloop 的示例,@xndrme,大概是QEventloop?我很难在 SO 或 Google 上找到有用的东西。提前致谢 嗯,嗯,事件循环我不是指QEventloop,问题是使用QThread你需要启动一个QApplicationhere,想法是如果您想在Qthreads 中添加插槽,则需要为每个线程启动一个事件循环,(这很简单,只需调用self.exec_())但也许我的回答不清楚,抱歉:(。请记住QThreads 仅在 QApplication 时。(如果您找到一种无需QApplication 即可做您想做的事情的方法,请给我打电话!;))【参考方案2】:

您必须声明您的自定义信号。这是一个与 pyqt 非常相似的 PySide 示例,但您可能需要对其进行修改。这也取决于版本。这是带有 PySide 1.2.1 的 Python 3.3 版本

class Test(QThread):
    test_signal = QtCore.Signal(object)

...
    while 1:
        print "Test running"
        self.test_signal.emit("a": "b")

...
t.test_signal.connect(callback)

【讨论】:

感谢您的反馈。这对于 PySide 应用程序更有用,但对 PyQt 也有一些应用程序。

以上是关于Python QT发出信号没有调用回调函数的主要内容,如果未能解决你的问题,请参考以下文章

QT信号槽连接语法总结

Qt - 从回调中发出信号

回调函数与Qt信号槽

QT--信号与槽

Qt源码阅读 信号槽的连接与调用

3信号与槽