QMetaObject::invokeMethod 找不到带参数的方法 [英] QMetaObject::invokeMethod doesn't find methods with parameters
问题描述
这是QMetaObject::invokeMethod没有找到方法的后续.调用没有参数的方法有效.但是将之前的问题扩展到带参数的方法让我再次失败.
This is a follow up of QMetaObject::invokeMethod doesn't find the method. Invoking a method without paramters works. But extending the previous question to methods with parameters brings me back to failure again.
请参阅以下 Python 示例脚本:
See the following example script in Python:
from PySide import QtCore
class Example(QtCore.QObject):
def __init__(self):
super().__init__()
@QtCore.Slot()
def dup(self):
beep('dup-class')
@QtCore.Slot(str)
def beep(self, text):
print(text)
@QtCore.Slot()
def dup(self):
beep('dup-local')
@QtCore.Slot(str)
def beep(text):
print(text)
if __name__ == '__main__':
QtCore.QMetaObject.invokeMethod(None, 'dup')
QtCore.QMetaObject.invokeMethod(None, 'beep', QtCore.Qt.AutoConnection, QtCore.QGenericArgument('text', 'beep-local'))
print('now some classy trials')
t = Example()
QtCore.QMetaObject.invokeMethod(t, 'dup')
QtCore.QMetaObject.invokeMethod(t, 'beep', QtCore.Qt.AutoConnection, QtCore.QGenericArgument('text', 'beep-class'))
QtCore.QMetaObject.invokeMethod(t, 'beep', QtCore.Qt.AutoConnection, QtCore.QGenericArgument('self', t), QtCore.QGenericArgument('text', 'beep-class-b'))
PySide 1.2.1 和 Python 3.3 在 Windows 7 和 Ubuntu 14.04 上的输出也是:
The output with PySide 1.2.1 and Python 3.3 on Windows 7 and Ubuntu 14.04 as well is:
now some classy trials
dup-class
QMetaObject::invokeMethod: No such method Example::beep(text)
QMetaObject::invokeMethod: No such method Example::beep(self,text)
这意味着对本地方法的 invokeMethod 调用以静默方式失败.只有对 Example:dup() 的调用给出了预期的输出.使 Example:beep(str) 工作的两次试验都失败了,尽管失败消息给出了实际应该存在的方法签名.
This means that the invokeMethod calls to local methods failed silently. Only the call to Example:dup() gave the expected output. The two trials to get Example:beep(str) to work failed, although the failure messages give method signatures that actually should exist.
我在 PySide 上提出了这个问题的早期版本邮件列表,但没有得到答复.
I posed an earlier version of this question on the PySide mailing list but it wasn't answered.
问题:如何使 QMetaObject::invokeMethod
在 Python Qt 绑定(最好在 PySide)中使用参数调用本地和类方法?
Question: How to make QMetaObject::invokeMethod
calling local and class method with parameters in the Python Qt bindings (preferably in PySide)?
顺便说一句:如果有人知道Signal:emit(...)
或QtCore.QTimer.singleShot(0, ...)
在下面做什么引擎盖,这也可以在这里提供帮助.毕竟,所有这些不同的方法都有非常相似的效果.
edit: By the way: if one knows what Signal:emit(...)
or QtCore.QTimer.singleShot(0, ...)
do under the hood, that could help here too. After all all these different approaches have very similar effects.
使用 'QString'
作为参数名称,警告消息消失,但 Python 整体失败并出现段错误.可能是 PySide 的一个实现错误.规则似乎是必须在 invokeMethod 中给出参数的 Qt-C++ 类型,在 Slots 中给出 Python 类型.
With 'QString'
as parameter name the warning messages disappear but Python fails as a whole with segfaults. It may be an implementation bug of PySide. The rule seems to be that one has to give the Qt-C++ types of the parameters in invokeMethod and the Python types in the Slots.
from PySide import QtCore
class Example(QtCore.QObject):
def __init__(self):
super().__init__()
@QtCore.Slot(str)
def beep(self, text='default'):
print(text)
if __name__ == '__main__':
app = QtCore.QCoreApplication([])
e = Example()
QtCore.QMetaObject.invokeMethod(e, 'beep', QtCore.Qt.AutoConnection, QtCore.QGenericArgument('QString', 'beep'))
QtCore.QTimer.singleShot(1000, app.quit)
app.exec_()
推荐答案
对于仍然对此感兴趣的任何人:
For anybody still interested in this:
从 1.2.4 版本开始,PySide 有问题,因为它没有包装 Q_ARG 和 Q_RETURN_ARG 宏.相反,它不明智地包装了 QGenericArgument 和 QGenericReturnArgument 类,它们是内部帮助类,并不打算直接实例化.因此,调用带参数的槽总是会导致分段错误.
As of version 1.2.4, PySide is buggy in that it doesn't wrap the Q_ARG and Q_RETURN_ARG macros. Instead, it unwisely wraps the QGenericArgument and QGenericReturnArgument classes, which are internal helper classes and not meant to be instanciated directly. As a result of this, invoking slots with arguments invariably results in a segmentation fault.
相比之下,PyQt 确实包装了宏而不是类,并且不会遇到同样的问题.
By comparison, PyQt does wrap the macros rather than the classes, and does not suffer from the same problems.
这篇关于QMetaObject::invokeMethod 找不到带参数的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!