"PySide.QtCore.Signal"对象没有属性"connect"。

18

我正在使用Python 3.4与Pyside 1.2.4和PyQt 4.8.7,当我尝试将Signal连接到Slot时,它会显示:

'PySide.QtCore.Signal'对象没有属性'connect'

我正在使用MVC:

Model:

from PySide.QtCore import Signal
class Model(object):

    def __init__(self):
        self.updateProgress = Signal(int)

控制器:

class Controller(QWidget):
"""
MVC Pattern: Represents the controller class

"""
def __init__(self, parent=None):
    super().__init__(parent)
    self.model = Model()
    self.model.updateProgress.connect(self.setProgress)

当我在Pycharm中按住CTRL并单击Signal类以查看其类时,它看起来像下面这样:

class Signal(object):
""" Signal """
def __call__(self, *args, **kwargs): # real signature unknown
    """ Call self as a function. """
    pass

def __getitem__(self, *args, **kwargs): # real signature unknown
    """ Return self[key]. """
    pass

def __init__(self, *args, **kwargs): # real signature unknown
    pass

@staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
    """ Create and return a new object.  See help(type) for accurate signature. """
    pass

def __str__(self, *args, **kwargs): # real signature unknown
    """ Return str(self). """
    pass

...然而根据PySide文档,在这里应该有connectdisconnectemit方法,可在以下链接中查看:

https://srinikom.github.io/pyside-docs/PySide/QtCore/Signal.html#PySide.QtCore.Signal.connect

提前感谢您的帮助。

3个回答

33

信号必须在类上定义,而不是实例上。该类必须是QObject的子类,或者是这种类的混合类。因此,可以选择以下任何一种:

class Model(QtCore.QObject):
    updateProgress = Signal(int)
或者:
class Mixin(object):
    updateProgress = Signal(int)

class Model(Mixin, QtCore.QObject):
    pass

1
将类继承自QObject并在类上定义信号即可实现。谢谢。 - LimitX
2
你能解释一下为什么它必须在类上定义吗? - Diego Palacios
@DiegoPalacios 这是一个实现细节。您需要查看源代码才能完全理解它,但基本上它使用与Python创建从类函数绑定实例方法相同的机制(即,信号对象是返回描述符的工厂函数)。以这种方式进行操作可以确保使用QMetaObject API(以及其他内容)对信号进行内省。 - ekhumoro

10
除了ekhumoro的回答之外,具有信号(signal)的类还需要调用super().__init__()。 忘记这样做可能会导致相同的错误。
class Model(QtCore.QObject):
    updateProgress = Signal(int)

    def __init__(self):
        super().__init__()  # This is required!
        # Other initialization...

在我还不知道自己会遇到大麻烦之前,你就已经帮我解决了一个大问题。非常感谢! - fr_andres

0

具体的工作示例:

class QWorker(QRunnable, QObject):
    started = Signal()
    finished = Signal()
    failed = Signal()

    def __init__(self, fn, *args, **kwargs):
        QObject.__init__(self)
        QRunnable.__init__(self)

        self.fn = fn
        self.args = args
        self.kwargs = kwargs

    def run(self):
        self.started.emit()
        try:
            self.fn(*self.args, **self.kwargs)
        except BaseException as e:
            self.failed.emit()
        else:
            self.finished.emit()

有趣的是,你必须执行 QObject.__init__(self)
而不是 super(QObject, self).__init__(),然后它就可以工作了


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接