如何正确地将 ComboBox 的模型从 python (pyQt5) 传递给 QML?

How to correctly to pass the model for ComboBox from python (pyQt5) to QML?

要在 QML 中(在 ComboBox 或 ListView 中)显示任何列表,我需要创建一个 class 作为该列表的模型。然后我需要将此 class 传递给 ContextProperty。但是,例如,如果我有 50 个组合框,那么我将有 50 个 class 必须传递给 ContextProperty。这是正确的方法吗?这不会影响内存消耗吗?

一个可能的解决方案是创建一个管理数据的模型,以便列表与角色相关联,如下所示:

import os
import random
import sys
from pathlib import Path

from PyQt5.QtCore import pyqtProperty, QCoreApplication, QObject, Qt, QUrl
from PyQt5.QtGui import QGuiApplication, QStandardItem, QStandardItemModel
from PyQt5.QtQml import QQmlApplicationEngine

CURRENT_DIRECTORY = Path(__file__).resolve().parent
ListDataRole = Qt.UserRole


class Manager(QObject):
    def __init__(self, parent=None):
        super().__init__(parent)
        self._model = QStandardItemModel()
        self._model.setItemRoleNames({ListDataRole: b"listdata"})

    @pyqtProperty(QObject, constant=True)
    def model(self):
        return self._model

    def add_list(self, l):
        item = QStandardItem()
        item.setData(l, ListDataRole)
        self._model.appendRow(item)


def main():
    app = QGuiApplication(sys.argv)

    manager = Manager()

    engine = QQmlApplicationEngine()
    engine.rootContext().setContextProperty("manager", manager)

    filename = os.fspath(CURRENT_DIRECTORY / "main.qml")
    url = QUrl.fromLocalFile(filename)

    def handle_object_created(obj, obj_url):
        if obj is None and url == obj_url:
            QCoreApplication.exit(-1)

    engine.objectCreated.connect(handle_object_created, Qt.QueuedConnection)

    engine.load(url)

    for _ in range(60):
        l = random.sample(range(10, 30), 5)
        manager.add_list(l)

    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Qt is awesome!!!")

    ScrollView {
        anchors.fill: parent

        Column {
            Repeater {
                model: manager ? manager.model : null

                ComboBox {
                    model: listdata
                }

            }

        }

    }

}