【问题标题】:How to correctly to pass the model for ComboBox from python (pyQt5) to QML?如何正确地将 ComboBox 的模型从 python (pyQt5) 传递给 QML?
【发布时间】:2021-09-01 08:17:17
【问题描述】:

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

【问题讨论】:

    标签: python pyqt pyqt5 qml


    【解决方案1】:

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

    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
                    }
    
                }
    
            }
    
        }
    
    }
    

    【讨论】:

    • 谢谢。如果以这种方式我需要为一个 ComboBox 传递一个列表?我可以在没有中继器的情况下以某种方式做到这一点吗?代码在这里 - pastebin.com/GgLvxacR
    • @testtests 我不明白你,我不明白链接的目的。在 SO 中,会提出具体问题,因此我们这些试图帮助您回答的人假设您提供的信息作为基础,并且根据我的观点,我的代码满足您的要求,我的回答有什么问题?请阅读How to Ask 并查看tour
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 2011-12-05
    • 2019-11-05
    • 2017-06-22
    • 2016-01-08
    • 1970-01-01
    相关资源
    最近更新 更多