1

我在使用 PySide Slot 装饰器时遇到了这种奇怪的情况。如果我使用 QtCore.Slot 装饰我的方法并且如果我尝试访问方法内部的 self.sender(),我会得到 None。如果我删除 QtCore.Slot() 装饰器。我正确地得到了发件人。这是一个最小的例子。

import sys
from PySide.QtCore import *
from PySide.QtGui import *

class Worker(QObject):
    def init(self):
        print "worker is ready."

    @Slot()
    def work(self):
        print "i am tired, %s" % self.sender()

app = QApplication(sys.argv)
button = QPushButton("Kick!")
button.show()

worker = Worker()
thread = QThread()
worker.moveToThread(thread)
thread.started.connect(worker.init)
button.clicked.connect(worker.work)
# app.connect(button, SIGNAL("clicked()"), worker, SLOT("work()"))
thread.start()

app.exec_()
sys.exit()

但是,如果我将新样式连接更改为旧方式,如注释行所示。

有用。有人可以解释这种行为吗?非常感谢。

4

1 回答 1

2

问题是接收信号的对象(您的 Worker 类)位于另一个线程中。

来自 Qt 文档:

QObject * QObject::sender () const [protected] 如果在由信号激活的槽中调用,则返回指向发送信号的对象的指针;否则返回 0。该指针仅在从该对象的线程上下文调用该函数的槽执行期间有效。

如果发送方被销毁,或者槽与发送方的信号断开连接,则此函数返回的指针无效。

警告:此函数违反了面向对象的模块化原则。但是,当许多信号连接到单个插槽时,访问发送器可能会很有用。

警告:如上所述,当插槽通过 Qt::DirectConnection 从与此对象的线程不同的线程调用时,此函数的返回值无效。请勿在此类场景中使用此功能。

如果您不将对象移动到另一个线程,它可以工作(示例在 python3 中,但在更改打印行后它将在 python 2 中工作):

import sys
from PySide.QtCore import *
from PySide.QtGui import *

class Worker(QObject):
    def init(self):
        print("worker is ready.")

    @Slot()
    def work(self):
        derp = self.sender()
        print ("i am tired, {}".format(derp))
        derp.setText("It works!")

app = QApplication(sys.argv)
button = QPushButton("Kick!")
button.show()

worker = Worker()
button.clicked.connect(worker.work)

app.exec_()
sys.exit()
于 2013-08-02T21:41:28.357 回答