我需要向使用 Python 中定义的自定义模型的 TableView 添加 header 。
我已经尝试用我的自定义 header 覆盖 QAbstractTableModel 中的 headerData 函数。我正在执行相同类型实现的此 C++ 示例中描述的相同系列步骤:Header to a TableView
不幸的是,标题仍然没有出现在表格的顶部。然而,该表确实包含来自覆盖 QAbstractTableModel 中的数据函数的数据。
python :
class RouteTableModel(QAbstractTableModel):
def __init__(self, parent=None, *args):
super().__init__()
self._datatable = None
self._header = {
0 : 'X',
1 : 'Y',
2 : 'Z'
}
def data(self, index, role=Value):
i = index.row()
j = index.column()
if role == self.Value:
return '{0}'.format(self._datatable[i][j]['value'])
elif role == self.Selected:
return self._datatable[i][j]['selected']
else:
return None
def headerData(self, section, orientation, role=Qt.DisplayRole):
if role == Qt.DisplayRole:
if orientation == Qt.Horizontal:
return self._header[section]
else:
return None
else:
return None
# create the application instance
app = QApplication(sys.argv)
# create a QML engine
engine = QQmlApplicationEngine()
# instantiate the TableModel class
xyztablemodel = RouteTableModel()
engine.rootContext().setContextProperty('XYZTableModel', xyztablemodel)
# load main QML file and start app engine
engine.load('view.qml')
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
QML:
import QtQuick 2.12
import QtQuick.Controls 2.12
GridLayout {
id: gridfpc2
flow: GridLayout.TopToBottom
rows: 4
columns: 2
rowSpacing: 20
columnSpacing: 35
TableView {
id: xyztable
Layout.rowSpan: 4
// Layout.alignment: Qt.AlignCenter
Layout.fillHeight: true
model: XYZTableModel
width: 350
delegate: CustomComp.XYZTableDelegate {
implicitWidth: parent.width / 3
implicitHeight: 20
}
}
}
Python 或 qml 代码中没有出现错误消息。我希望标题填充在 TableView 中的列上方,但它们没有显示。
在您在问题中指出的示例中,它来自与 QML 提供的 TableView 非常不同的 QTableView。在您的情况下,您使用的是 QtQuick 的 TableView。此 TableView 没有 header ,因此您必须实现它,在我的示例中,我将使用 Repeater。另一方面,无法从 QML 访问 headerData,因此我将使用 @Slot() 实现 C++ 的 Q_INVOKABLE,将返回函数的变量类型的结果作为参数传递:
主.py
from PySide2 import QtCore, QtGui, QtQml
class RouteTableModel(QtCore.QAbstractTableModel):
def __init__(self, parent=None):
super().__init__(parent)
self._header = {0: "X", 1: "Y", 2: "Z"}
def columnCount(self, parent=QtCore.QModelIndex()):
return 3
def rowCount(self, parent=QtCore.QModelIndex()):
return 100
def data(self, index, role=QtCore.Qt.DisplayRole):
i = index.row()
j = index.column()
if role == QtCore.Qt.DisplayRole:
return "{}-{}".format(i, j)
@QtCore.Slot(int, QtCore.Qt.Orientation, result="QVariant")
def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
if role == QtCore.Qt.DisplayRole:
if orientation == QtCore.Qt.Horizontal:
return self._header[section]
else:
return str(section)
if __name__ == "__main__":
import os
import sys
app = QtGui.QGuiApplication(sys.argv)
engine = QtQml.QQmlApplicationEngine()
xyztablemodel = RouteTableModel()
engine.rootContext().setContextProperty("XYZTableModel", xyztablemodel)
current_dir = os.path.dirname(os.path.realpath(__file__))
filename = os.path.join(current_dir, "view.qml")
engine.load(QtCore.QUrl.fromLocalFile(filename))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
view.qml
import QtQuick 2.12
import QtQuick.Controls 2.4
import QtQuick.Window 2.11
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
color: '#222222'
TableView {
id: tableView
columnWidthProvider: function (column) { return 100; }
rowHeightProvider: function (column) { return 60; }
anchors.fill: parent
leftMargin: rowsHeader.implicitWidth
topMargin: columnsHeader.implicitHeight
model: XYZTableModel
width: 350
delegate: Rectangle {
implicitWidth: 100
implicitHeight: 50
Text {
text: display
}
}
Rectangle { // mask the headers
z: 3
color: "#222222"
y: tableView.contentY
x: tableView.contentX
width: tableView.leftMargin
height: tableView.topMargin
}
Row {
id: columnsHeader
y: tableView.contentY
z: 2
Repeater {
model: tableView.columns > 0 ? tableView.columns : 1
Label {
width: tableView.columnWidthProvider(modelData)
height: 35
text: XYZTableModel.headerData(modelData, Qt.Horizontal)
color: '#aaaaaa'
font.pixelSize: 15
padding: 10
verticalAlignment: Text.AlignVCenter
background: Rectangle { color: "#333333" }
}
}
}
Column {
id: rowsHeader
x: tableView.contentX
z: 2
Repeater {
model: tableView.rows > 0 ? tableView.rows : 1
Label {
width: 40
height: tableView.rowHeightProvider(modelData)
text: XYZTableModel.headerData(modelData, Qt.Vertical)
color: '#aaaaaa'
font.pixelSize: 15
padding: 10
verticalAlignment: Text.AlignVCenter
background: Rectangle { color: "#333333" }
}
}
}
ScrollIndicator.horizontal: ScrollIndicator { }
ScrollIndicator.vertical: ScrollIndicator { }
}
}
我是一名优秀的程序员,十分优秀!