QMetaObject :: invokeMethod找不到该方法

时间:2014-04-17 08:08:32

标签: python qt pyside qtcore qt-signals

我想使用QMetaObject :: invokeMethod来调用对象的方法(稍后它将在另一个线程中运行,然后invokeMethod派上用场)。我在Python 3.3上使用PySide 1.2.1的Qt 4.8绑定。完整的例子是:

from PySide import QtCore

class Tester(QtCore.QObject):
    def __init__(self):
        super().__init__()

    def beep(self):
        print('beep')

if __name__ == '__main__':
    t = Tester()
    QtCore.QMetaObject.invokeMethod(t, 'beep', QtCore.Qt.AutoConnection)

输出是:

QMetaObject::invokeMethod: No such method Tester::beep()

虽然我期待beep。该方法未被调用。

那有什么不对?看起来很简单,我找不到错误。


编辑:我使用方法上的`@ QtCore.Slot'修饰工作了。感谢评论和答案。

1 个答案:

答案 0 :(得分:2)

您不能调用常规方法,只能调用信号和插槽。这就是为什么它不适合你。有关详细信息,请参阅QMetaObject documentation

  

在对象obj上调用成员(信号或插槽名称)。如果可以调用该成员,则返回true。如果没有这样的成员或参数不匹配,则返回false。

试试这个装饰者:

...
@QtCore.Slot()
def beep(self):
    print('beep')
...

有关详细信息,请参阅following documentation以及this one

  

使用QtCore.Slot()

     

使用装饰器QtCore.Slot()分配和重载插槽。同样,要定义签名,只需传递类似QtCore.Signal()类的类型。与Signal()类不同,要重载函数,不要将每个变量作为元组或列表传递。相反,您必须为每个不同的签名定义一个新的装饰器。下面的示例部分将更清楚。

     

另一个区别在于其关键字。 Slot()接受名称和结果。 result关键字定义将返回的类型,可以是C或Python类型。 name的行为与Signal()中的行为相同。如果没有任何内容作为名称传递,则新插槽将与正在装饰的函数具有相同的名称。