如何正确地将 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
}
}
}
}
}
要在 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
}
}
}
}
}