【问题标题】:Signal-Slot Connection between Creator and Created ClassCreator 和 Created 类之间的信号槽连接
【发布时间】:2012-02-27 07:22:27
【问题描述】:

我有一个问题。

我有两个类,A 和 B。A 创建 B 类型的对象,并发出如下信号:

QtCore.QObject.emit(QtCore.SIGNAL('mySignal'), "Hello World")

B 可以看到 A 中的方法,因为 A 在创建 B 时将“self”作为参数传递给构造函数,如 here 所述。

现在,我想在 B 中为 A 中发出的信号编写一个插槽,如下所示:

self.connect(self._creator, QtCore.SIGNAL('mySignal'), mySlot)

这里我想提一下,A 和 B 都继承自 QtCore.QObject。 mySlot 方法只是应该打印它从信号中接收到的值作为参数。

当我运行它时,我得到这个错误:

QObject.emit(SIGNAL(), ...):未绑定方法的第一个参数必须具有类型'QObject'

在两个类的 init() 中,我都添加了这个:

QtCore.QObject.__init__(self)

不添加这个,我得到错误:

RuntimeError: 底层 C/C++ 对象已被删除

我对 Qt 没有经验。我不明白出了什么问题。请帮忙。

【问题讨论】:

    标签: python pyqt pyqt4 python-2.7 signals-slots


    【解决方案1】:

    未绑定方法的第一个参数必须是“QObject”类型

    正如错误所说,您需要为QtCore.QObject.emit 传递对A 的引用或使用实例方法调用它:

    QtCore.QObject.emit(self, QtCore.SIGNAL('mySignal'), "Hello World")
    

    或者

    self.emit(QtCore.SIGNAL('mySignal'), "Hello World")
    

    完整的工作示例(如果我理解正确的话):

    from PyQt4 import QtCore
    
    class A(QtCore.QObject):
        mySignal = QtCore.SIGNAL('mySignal(QString)')
        def __init__(self):
            QtCore.QObject.__init__(self)
    
        def create_b(self):
            return B(self)
    
        def some_action(self):
            QtCore.QObject.emit(self, QtCore.SIGNAL('mySignal'), "Hello World")
            # this will work too
            self.emit(QtCore.SIGNAL('mySignal'), "Hello World")
    
    class B(QtCore.QObject):
        def __init__(self, creator):
            QtCore.QObject.__init__(self)
            self._creator = creator
            self.connect(self._creator, QtCore.SIGNAL('mySignal'), self.mySlot)
    
        def mySlot(self, str):
            print str
    
    a = A()
    b = a.create_b()
    a.some_action()
    

    更好的解决方案是使用New-style Signals and Slots

    这里是你的例子:

    from PyQt4 import QtCore
    
    class A(QtCore.QObject):
        mySignal = QtCore.pyqtSignal(str)
        def __init__(self):
            QtCore.QObject.__init__(self)
    
        def create_b(self):
            return B(self)
    
        def some_action(self):
            self.mySignal.emit("Hello World")
    
    class B(QtCore.QObject):
        def __init__(self, creator):
            QtCore.QObject.__init__(self)
            self._creator = creator
            self._creator.mySignal.connect(self.mySlot)
    
        def mySlot(self, str):
            print str
    
    a = A()
    b = a.create_b()
    a.some_action()
    

    【讨论】:

    • 其实和这个略有不同。 B 在我的例子中是一个线程,所以在 A 里面,我有:self.b = B(self) self.b.start() 当我运行你的例子时,它运行良好,但是当我在我的例子中使用它时,它说:underlying C/C++对象已被删除
    • 我知道这是所有权语义的问题,但不知道如何解决。其他人从 A 创建了对象,A 从 B 创建了对象,现在 A 必须发送信号,B 必须有一个插槽。不知何故,Python 不理解我的编码的所有权语义。但是由于我无法控制从 A 中创建对象,只有这样才能触发从 B 中创建对象,所以我不能像在一个小的独立 Python 脚本中那样在外部编写对象创建语句。
    • @SubhamoySengupta,将重现您的问题的代码添加到问题中。目前还不清楚。这是线程pastebin.com/RMJtJskV 的工作示例(它是编辑代码,QThread.__init__ 而不是QObject.__init__
    • 这里是link 这不会执行,因为它是大量代码的一小部分。我已经尝试删除大部分噪音以便您理解。
    • 我忘了说,类不能从 QThread 继承。如果他们这样做,其他事情将停止工作:(它们是常规线程。
    猜你喜欢
    • 1970-01-01
    • 2018-09-23
    • 2011-07-14
    • 2012-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-14
    相关资源
    最近更新 更多