PySide QtCore.Slot装饰器不适用于方法中的self.sender() [英] PySide QtCore.Slot decorator does not work with self.sender() inside a method

查看:522
本文介绍了PySide QtCore.Slot装饰器不适用于方法中的self.sender()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I came across this weirdness in using PySide Slot decorator. If I decorate my method using QtCore.Slot and if I try to access self.sender() inside the method, I get None. If I remove the QtCore.Slot() decorator. I get the sender properly. Here is a minimal example.

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()

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

However, if I change the new style connection to the old way, as shown in the commented line.

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

It works. Can someone explain this behavior? Thanks a lot.

推荐答案

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

The problem is that the object that receive the signal (your Worker class) lives in another thread.

来自Qt文档:

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

QObject * QObject::sender () const [protected] Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; otherwise it returns 0. The pointer is valid only during the execution of the slot that calls this function from this object's thread context.

如果发送方被破坏或插槽与发送方的信号断开连接,则此函数返回的指针将变为无效.

The pointer returned by this function becomes invalid if the sender is destroyed, or if the slot is disconnected from the sender's signal.

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

Warning: This function violates the object-oriented principle of modularity. However, getting access to the sender might be useful when many signals are connected to a single slot.

警告:如上所述,当从与该对象的线程不同的线程通过Qt :: DirectConnection调用插槽时,此函数的返回值无效 >.请勿在这种情况下使用此功能.

Warning: As mentioned above, the return value of this function is not valid when the slot is called via a Qt::DirectConnection from a thread different from this object's thread. Do not use this function in this type of scenario.

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

If you don't move the object to the other thread, it works (the examples is in python3, but it will work in python 2, after changing the print lines):

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()

这篇关于PySide QtCore.Slot装饰器不适用于方法中的self.sender()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆