我正在尝试使用 QML
TableView
和 Qt for Python / PySide6 在 Qt Quick 中显示非常简单的 2D 数据。这是我想要创建的示例:
在下面的代码中,我向 QML 公开了一个单例对象,它提供了
QStandardItemModel
作为 QObject 属性,但无法显示任何内容。我的上述尝试有什么问题吗?
// Main.qml
import QtQuick
import QtQuick.Window
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.qmlmodels
import com.simplified
Window {
width: 740
height: 540
visible: true
title: "Python log viewer"
TableView {
id: log
anchors.fill: parent
columnSpacing: 1
rowSpacing: 1
clip: true
model: Simplified.log
delegate: Rectangle {
border.width: 1
clip: true
Text {
text: display
anchors.centerIn: parent
}
}
}
}
# main.py
QML_IMPORT_NAME = "com.simplified"
QML_IMPORT_MAJOR_VERSION = 1
# Core dependencies
from pathlib import Path
import sys
# Package dependencies
from PySide6.QtCore import QObject, Signal, Property, Qt
from PySide6.QtGui import QGuiApplication, QStandardItemModel, QStandardItem
from PySide6.QtQml import QQmlApplicationEngine, QmlElement, QmlSingleton
LOG_ENTRIES = [
{
"Timestamp": "2024-07-01 19:16:03.326",
"Name": "root.child",
"Level": "DEBUG",
"Message": "This is a debug message",
},
{
"Timestamp": "2024-07-01 19:16:03.326",
"Name": "root.child",
"Level": "INFO",
"Message": "This is an info message",
},
]
FIELD_NAMES = ["Timestamp", "Name", "Level", "Message"]
@QmlElement
@QmlSingleton
class Simplified(QObject):
log_changed = Signal()
def __init__(self) -> None:
super().__init__()
_ = self.log
self.log_changed.emit()
@Property(QStandardItemModel, notify=log_changed)
def log(self):
lines = LOG_ENTRIES
table = QStandardItemModel(len(lines), len(FIELD_NAMES))
table.setHorizontalHeaderLabels(FIELD_NAMES)
for line in lines:
row = [QStandardItem(str(line[key])) for key in FIELD_NAMES]
table.appendRow(row)
return table
if __name__ == "__main__":
application = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
qml_file = Path(__file__).resolve().parent / "qml" / "Main.qml"
engine.load(qml_file)
if not engine.rootObjects():
sys.exit(-1)
engine.singletonInstance("com.simplified", "Simplified")
sys.exit(application.exec())
您需要存储模型。 QML TableView 不会像
QAbstractItemView
派生类一样拥有该模型。在 TableView 的 QML 实现多次访问之后,从 Simplified.log()
返回的模型将在事件循环中被销毁。在官方示例中检查模型的生命周期。
此外,您将
Simplified.log
属性的类型指定为 QStandardItemModel
,但 QML 引擎的属性类型分派实现并不知道,因为它默认情况下未注册。请参阅参考资料,例如QML 类型系统 和数据类型转换。
以下是固定代码的示例。
@QmlElement
@QmlSingleton
class Simplified(QObject):
log_changed = Signal()
def __init__(self):
super().__init__()
self.model = None
@Property(QObject, notify=log_changed)
def log(self):
if self.model is None:
self.model = model = QStandardItemModel()
for line in LOG_ENTRIES:
row = [QStandardItem(str(line[key])) for key in FIELD_NAMES]
model.appendRow(row)
return self.model