QMetaObject::invokeMethod 找不到方法
我想用 QMetaObject::invokeMethod 来调用一个对象的方法(以后这个方法会在另一个线程中运行,这时候 invokeMethod 就很有用了)。我在 Python 3.3 上使用的是 Qt 4.8 的 PySide 1.2.1 版本。完整的例子是:
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 个回答
4
你不能调用普通的方法,只能使用信号和槽。这就是为什么你遇到问题的原因。想了解更多,可以查看QMetaObject的文档:
这个方法会在对象obj上调用某个成员(信号或槽的名字)。如果成功调用了这个成员,就返回true。如果没有这个成员或者参数不匹配,就返回false。
试试这个装饰器:
...
@QtCore.Slot()
def beep(self):
print('beep')
...
使用QtCore.Slot()
槽是通过装饰器QtCore.Slot()来定义和重载的。要定义一个签名,只需像使用QtCore.Signal()类那样传递类型。与Signal()类不同的是,重载一个函数时,你不需要把每种变化都作为元组或列表传递。相反,你需要为每种不同的签名定义一个新的装饰器。下面的示例部分会让这一点更清楚。
另一个不同之处在于它的关键字。Slot()接受一个名字和一个结果。结果关键字定义了返回的类型,可以是C语言类型或Python类型。name的行为和Signal()中的一样。如果没有传递名字,那么新的槽将和被装饰的函数同名。