【发布时间】:2020-06-29 18:57:42
【问题描述】:
我遇到了一个看起来很像现代 Python 版本的错误,该错误是多年前在 (C++) Qt 中修复的:Can't call slot or Q_INVOKABLE from QML in subclass of QQmlPropertyMap
我在我的系统上测试了问题中的示例(Qt 5.15.0,根据需要修改语法)并验证它确实已修复;对象的槽被正确访问,无论是继承自 QObject 还是 QQmlPropertyMap。
但是,仍然使用 Qt 5.15.0,从 PySide2 工作似乎复制了同样的问题:
main.py:
from PySide2.QtCore import QObject, Property, Slot
from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine, QQmlPropertyMap
class MyObj(QObject):
@Property(str)
def field(self):
return 'Field from QObject'
@Slot()
def test_func(self):
print('QObject signal worked')
class MyMap(QQmlPropertyMap):
def __init__(self):
super().__init__()
self.insert('field', 'Field from QQmlPropertyMap')
@Slot()
def test_func(self):
print('QQmlPropertyMap signal worked')
app = QGuiApplication()
engine = QQmlApplicationEngine()
qobj = MyObj()
engine.rootContext().setContextProperty('qobj', qobj)
qmap = MyMap()
engine.rootContext().setContextProperty('qmap', qmap)
engine.load('main.qml')
app.exec_()
main.qml:
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
visible: true
width: 200
height: 200
Text {
text: qobj.field + '\n' + qmap.field
anchors.centerIn: parent
}
MouseArea {
anchors.fill: parent
onClicked: {
qobj.test_func();
qmap.test_func();
}
}
}
这两个字段都在生成的窗口中正确显示,但单击它会产生此控制台输出:
QObject slot worked
file:///Users/charles/Projects/qt/map-signal-test/main.qml:20: TypeError: Property 'test_func' of object QQmlPropertyMap(0x7fb954f5f460) is not a function
我不太了解 PySide2 是如何实现的。这是同一个错误,未修复还是重新出现?或者是别的什么?无论哪种情况,是否有解决方法?
编辑: 回应 eyllanesc 在下面的回答。虽然您发布的代码重现了 C++ 中的错误,但这个略有不同的类定义(源自上面链接的旧问题)可以正常工作:
class MyMap: public QQmlPropertyMap {
Q_OBJECT
public:
MyMap(QObject* parent = 0): QQmlPropertyMap(this, parent) {}
public slots:
Q_INVOKABLE void test_func() {
qDebug() << "QQmlPropertyMap signal worked";
}
};
我对 C++ 了解不够,无法理解其中的含义。
【问题讨论】: