Доступ к атрибутам QVariant из QML с использованием PySide2 - PullRequest
0 голосов
/ 03 октября 2019

У меня есть @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

enter image description here

Исходя из привычки использовать Qt с C ++, я бы традиционно делал что-то вроде Q_DECLARE_METATYPE, чтобы сделать мой пользовательский тип доступным какQVariant но PySide2-эквивалент не существует.

...