PyQt4.QtCore.pyqtSignal 对象没有属性“连接”
Posted
技术标签:
【中文标题】PyQt4.QtCore.pyqtSignal 对象没有属性“连接”【英文标题】:PyQt4.QtCore.pyqtSignal object has no attribute 'connect' 【发布时间】:2011-02-27 13:23:19 【问题描述】:我在制作的课程中遇到了自定义信号问题。
相关代码:
self.parse_triggered = QtCore.pyqtSignal()
def parseFile(self):
self.emit(self.parse_triggered)
这两个都属于类:RefreshWidget。 在它的父类中,我有:
self.refreshWidget.parse_triggered.connect(self.tabWidget.giveTabsData())
当我尝试运行程序时,我得到了错误:
AttributeError: 'PyQt4.QtCore.pyqtSignal' object has no attribute 'connect'
帮助? 提前致谢。
【问题讨论】:
self.tabWidget.giveTabsData()
看起来很可疑,因为它需要返回一个函数/处理程序,但这不应该与你得到的实际错误有关。否则,它看起来不错。
我遇到了完全相同的问题。如果您找到解决方案,您能否发布并编辑问题所在?
【参考方案1】:
我和你有同样的问题。
尝试移动
self.parse_triggered = QtCore.pyqtSignal()
在您的构造函数之外,但在您的类声明中。所以不要看起来像这样:
class Worker(QtCore.QThread):
def __init__(self, parent = None):
super(Worker, self).__init__(parent)
self.parse_triggered = QtCore.pyqtSignal()
应该是这样的:
class Worker(QtCore.QThread):
parse_triggered = QtCore.pyqtSignal()
def __init__(self, parent = None):
super(Worker, self).__init__(parent)
这可能根本不是您想要的,但它对我有用。无论如何,我还是切换回了旧式信号,因为我还没有在新式信号中找到一种方法来获得未定义数量或类型的参数。
【讨论】:
有人能解释这是为什么吗? 这有问题。信号将在每个实例之间共享。 之所以可行是由于 PyQt 库内部实现pyqtSignal
的方式。具体来说,在Support for Signals and Slots 下,我们发现该库区分未绑定和绑定信号。魔术执行如下:“信号(特别是未绑定的信号)是QObject
的子类的类的属性。当信号被引用为类实例的属性时,PyQt5会自动将实例绑定到信号以创建绑定信号。”
还要注意,超类也必须初始化。我错过了子类 __init__() 函数中的调用,假设它会自动完成并且导致关于信号的相同错误消息。
有没有办法解决这个问题,如果该类已经通过 Qt Creator 定义,大量布局并使用 pyuic 动态翻译,或者我必须自己手动子类化它以启用像 @ 一样的信号987654327@?【参考方案2】:
如果您未能在自定义类中调用 super()
或 QObject.__init__()
,也会收到该错误消息。
在 Python 中 Qt 的类中定义自定义信号的清单:
您的类派生自 QObject(直接或间接) 您的班级__init__
调用super()
(或直接调用QObject.__init__()
。)
您的信号被定义为类变量,而不是实例变量
信号的签名(形式参数)与您将连接到信号的任何插槽的签名相匹配,例如()
或 (int)
或 (str)
或 ((int,), (str,))
【讨论】:
我在这里遇到的错误是“信号必须绑定到 QObject 实例,而不是__init__
。感谢您的提示!__init__
方法中同时调用 QObject.__init__(self)
和 QRunnable.__init__(self)
。【参考方案3】:
我最近开始使用 PySide(诺基亚自己的 PyQt 版本),并看到了与自定义新型信号完全相同的行为(和解决方案)。我对该解决方案最大的担忧是,当我有该类的多个实例(在我的情况下为 QThreads)时,使用类变量来保存信号会搞砸。
据我所知,QtCore.QObject.__init__(self)
在类中找到 Signal 变量并为实例创建该 Signal 的副本。我不知道 QObject.__init__()
做了什么,但生成的 Signal 可以正确执行 connect()
、disconnect()
和 emit()
方法(以及 __getitem__()
方法),而类 Signal 或独立 Signal 变量是在QObject派生类没有这些方法,不能正常使用。
【讨论】:
【参考方案4】:要使用信号/槽系统,您需要有一个 QObject 继承类。
这是一个简单的例子:
from PySide import QtCore
class LivingBeing(QtCore.QObject):
bornSignal = QtCore.Signal() # initialise our signal
def __init__(self,name):
QtCore.QObject.__init__(self) # initialisation required for object inheritance
self.bornSignal.connect(self.helloWorld) # connect the born signal to the helloworld function
self.name = name #
self.alive = False
def summonFromClay(self):
self.alive = True
self.bornSignal.emit() # emit the signal
def helloWorld(self):
print "Hello World !, my name is %s, this place is so great !" % self.name
# now try the little piece of code
if __name__ == '__main__':
firstHuman = LivingBeing('Adam')
firstHuman.summonFromClay()
【讨论】:
【参考方案5】:我遇到了同样的问题。 我忘记了如果一个类使用信号,那么它必须从 QObject 继承。我正在做一些重构,并没有注意这一点。
【讨论】:
【参考方案6】:为什么你直接连接到信号,而你可以这样做
self.connect(widget, SIGNAL('parse_triggered()'), listener.listening_method)
?
其中 self 是例如表单本身,并且可能与侦听器相同
【讨论】:
据说这是执行 connect() 的“旧方式”。根据我的阅读,即使存在错误,该方法也不会出现任何错误。 这是老式的信号和槽。两者都有效,但人们倾向于认为新风格更优雅/pythonic。以上是关于PyQt4.QtCore.pyqtSignal 对象没有属性“连接”的主要内容,如果未能解决你的问题,请参考以下文章