PyQt4.QtCore.pyqtSignal对象没有'connect'属性

70 投票
6 回答
63101 浏览
提问于 2025-04-15 23:32

我在自己写的一个类里遇到了自定义信号的问题。

相关代码:

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'

有人能帮帮我吗?

提前谢谢大家。

6 个回答

10

我最近开始使用PySide(诺基亚自己版本的PyQt),发现自定义的新风格信号有一样的表现和解决方案。我最担心的是,使用类变量来保存信号会在我有多个这个类的实例时搞乱事情(在我的情况下是QThreads)。

从我看到的情况来看,QtCore.QObject.__init__(self)会在类中找到信号变量,并为这个实例创建一个信号的副本。我不知道QObject.__init__()具体做了什么,但结果是这个信号有正常的connect()disconnect()emit()方法(还有一个__getitem__()方法),而类信号或者在QObject派生类外部创建的独立信号变量则没有这些方法,不能正常使用。

79

如果你在自定义类中没有调用 super()QObject.__init__(),你也会看到这个错误信息。

在Qt的Python中定义自定义信号时,可以参考以下清单:

  • 你的类需要继承自QObject(可以直接继承,也可以间接继承)。
  • 你的类的 __init__ 方法要调用 super()(或者直接调用 QObject.__init__())。
  • 你的信号要定义为类变量,而不是实例变量。
  • 你的信号的参数(也就是它的签名)要和你要连接的槽函数的参数匹配,比如 ()(int)(str) 或者 ((int,), (str,))
139

我遇到过和你完全一样的问题。

试着把

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)

这可能不是你想要的解决方案,但对我来说有效。反正我还是回到了旧式信号,因为我还没找到新式信号可以处理不定数量或类型参数的方法。

撰写回答