Я пытаюсь преобразовать существующее приложение PySide2 / QtWidgets в PySide2 / QML. Я пытаюсь получить список настраиваемых объектов из вызова службы Python с помощью MouseArea
щелчка QML.
В настоящее время у меня есть основной скрипт (main.py
), который запускает QQuickView
, содержащий мой QML (содержащийся в main.qml
). Он также регистрирует настраиваемый тип для моей модели (Role
, определенный в role.py
) и предоставляет экземпляр моего класса обслуживания (содержащийся в mock_role_service.py
) корневому контексту представления.
Мой QML отображается правильно, и я могу щелкнуть свой MouseArea
, но вместо того, чтобы вернуться List[Role]
, я, похоже, получаю QVariant
кортеж. В частности, QVariant(PySide::PyObjectWrapper, )
.
Соответствующие файлы: mock_role_service.py
:
class MockRoleService(QObject):
def __init__(self):
super().__init__()
self.next_id = 5
self.records = {
1: Role(id_=1,
name='Admin'),
2: Role(id_=2,
name='User')
}
@Slot(result=list)
def find_all(self) -> List[Role]:
return list(self.records.values())
main.py
:
...
app = QGuiApplication(sys.argv)
qmlRegisterType(Role, 'Models', 1, 0, 'Role')
view = QQuickView()
url = QUrl('Views/main.qml')
view.setSource(url)
view.setResizeMode(QQuickView.SizeRootObjectToView)
role_service = MockRoleService()
view.rootContext().setContextProperty("roleService", role_service)
if view.status() == QQuickView.Error:
sys.exit(-1)
view.show()
sys.exit(app.exec_())
main.qml
:
...
MouseArea {
onClicked: {
console.log(roleService.find_all())
for (role in roleService.find_all()) {
console.log(role.get_id())
}
}
}
...
Результатом первого console.log()
вызова является QVariant(PySide::PyObjectWrapper, )
, а цикл for никогда не запускается.
Мне удалось найти только пару похожих проблем в Интернете и их общее решение (например, в этом ответ) заключается в том, чтобы установить значение свойства класса и указать его тип QVariantList
. Это связано с тем, что PySide2 явно покончил с их QVariant
-подобными типами, поэтому я не могу правильно указать тип результата слота.
Однако я не уверен, что это решение подходит для данной ситуации, потому что я имею дело с объектом службы. Установка свойства класса обслуживания для хранения возвращаемого значения кажется хрупкой. Нет другого способа добиться этого?