使用PySide2从QML访问QVariant属性

时间:2019-10-03 14:21:06

标签: python qt qml pyside2

我有一个@dataclass,其中包含要使用QML在UI中显示的属性列表。但是,当尝试显示信息时,它将显示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

从习惯于在C ++中使用Qt,我传统上会做类似Q_DECLARE_METATYPE的事情来使我的自定义类型可以作为QVariant使用,但PySide2等效项似乎并不存在。

0 个答案:

没有答案