【问题标题】:'PySide.QtCore.Signal' object has no attribute 'connect''PySide.QtCore.Signal' 对象没有属性 'connect'
【发布时间】:2016-08-02 06:22:24
【问题描述】:

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

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

我正在使用 MVC:

型号:

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

提前感谢您的帮助

【问题讨论】:

    标签: python pyside signals-slots qobject


    【解决方案1】:

    信号必须在类上定义,而不是在实例上。该类必须是QObject 的子类,或者是此类的mixin。所以要么:

    class Model(QtCore.QObject):
        updateProgress = Signal(int)
    

    或:

    class Mixin(object):
        updateProgress = Signal(int)
    
    class Model(Mixin, QtCore.QObject):
        pass
    

    【讨论】:

    • 使类继承自 QObject 并在类上定义信号。谢谢
    • 你能解释一下为什么必须在类上定义它吗?
    • @DiegoPalacios 这是一个实现细节。您需要查看源代码才能完全理解它,但本质上它使用的机制与 python 用于从类函数创建绑定实例方法的机制相同(即信号对象是返回描述符的工厂函数)。以这种方式做事可确保信号可以使用 QMetaObject API(除其他外)进行内省。
    【解决方案2】:

    除了ekhumoro的回答,有信号的类也需要调用super().__init__()。忘记这样做会导致同样的错误。

    class Model(QtCore.QObject):
        updateProgress = Signal(int)
    
        def __init__(self):
            super().__init__()  # This is required!
            # Other initialization...
    

    【讨论】:

    • 在我知道自己会拥有一个之前就让我头疼不已。非常感谢!
    【解决方案3】:

    具体的工作示例:

    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__(),那么它可以工作

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-01
      • 2021-08-03
      相关资源
      最近更新 更多