У меня есть @dataclass
, который содержит список атрибутов, которые я хочу отобразить в своем пользовательском интерфейсе, используя QML. Однако, когда он пытается отобразить информацию, он скажет undefined
. Я использую PySide2 версии 5.13.1.
main.py
import sys
from PySide2.QtCore import QUrl
from PySide2.QtQml import QQmlApplicationEngine, qmlRegisterType
from PySide2.QtWidgets import QApplication
from information_item import InformationItem
import qml_rc
if __name__ == "__main__":
app = QApplication(sys.argv)
qmlRegisterType(InformationItem, "InformationItem", 1, 0, "InformationItem")
engine = QQmlApplicationEngine()
engine.load(QUrl("qrc:/main.qml"))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
information.py
from typing import List
from dataclasses import dataclass, field
@dataclass
class Information:
first_name: str = ""
last_name: str = ""
phone_numbers: List[str] = field(default_factory=list)
information_item.py
from typing import List
from PySide2.QtCore import Property
from PySide2.QtQuick import QQuickItem
from information import Information
class InformationItem(QQuickItem):
def __init__(self, parent: QQuickItem = None) -> None:
super().__init__(parent)
self._information = Information("John", "Doe", ["(123) 456-7890", "(321) 654-0987"])
@Property("QVariant", constant=True)
def information(self) -> Information:
print(f"INFORMATION: {self._information.first_name} {self._information.last_name} {self._information.phone_numbers[0]} {self._information.phone_numbers[1]}")
return self._information
main.qml
import QtQuick 2.13
import QtQuick.Controls 2.13
ApplicationWindow {
width: 500
height: 500
visible: true
InformationItem {
anchors.fill: parent
}
}
InformationItem.qml
import QtQuick 2.13
import InformationItem 1.0
InformationItem {
id: informationItem
anchors.fill: parent
Column {
Text {
text: "First Name " + informationItem.information.first_name
}
Text {
text: "Last Name " + informationItem.information.last_name
}
Text {
text: "Phone Number 1 " + informationItem.information.phone_numbers[0]
}
Text {
text: "Phone Number 2 " + informationItem.information.phone_numbers[1]
}
}
Component.onCompleted: {
console.log("informationItem.information: " + informationItem.information)
}
}
Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[packages]
PySide2 = "==5.13.1"
[requires]
python_version = "3.7"
Я собираю и запускаю свою программу следующим образом:
$ pipenv install
$ pipenv run pyside2-rcc -o qml_rc.py qml.qrc
$ pipenv run python main.py
Когда она запускается, я получаю следующий вывод:
INFORMATION: John Doe (123) 456-7890 (321) 654-0987
INFORMATION: John Doe (123) 456-7890 (321) 654-0987
INFORMATION: John Doe (123) 456-7890 (321) 654-0987
INFORMATION: John Doe (123) 456-7890 (321) 654-0987
INFORMATION: John Doe (123) 456-7890 (321) 654-0987
qml: informationItem.information: QVariant(PySide::PyObjectWrapper, )
qrc:/InformationItem.qml:19: TypeError: Cannot read property '0' of undefined
qrc:/InformationItem.qml:23: TypeError: Cannot read property '1' of undefined
Исходя из привычки использовать Qt с C ++, я бы традиционно делал что-то вроде Q_DECLARE_METATYPE
, чтобы сделать мой пользовательский тип доступным какQVariant
но PySide2-эквивалент не существует.