gpt4 book ai didi

python - 具有动态宽度列的 QML TableView

转载 作者:太空宇宙 更新时间:2023-11-03 23:55:18 25 4
gpt4 key购买 nike

我在 PySide2 Qt 5.13.0 中创建了一个 TableView。我想要一个 TableView 来填充父项的宽度,但除非我拖动表格,否则它不会调整列的大小。从程序一开始,我就希望列更宽。

enter image description here

主要.py

import sys

from PySide2.QtCore import QUrl
from PySide2.QtQml import QQmlApplicationEngine, qmlRegisterType
from PySide2.QtWidgets import QApplication

from table_model import TableModel

import qml_rc # noqa: F401


if __name__ == "__main__":
app = QApplication(sys.argv)

engine = QQmlApplicationEngine()

qmlRegisterType(TableModel, "TableModel", 1, 0, "TableModel")

engine.load(QUrl("qrc:/main.qml"))

if not engine.rootObjects():
sys.exit(-1)

sys.exit(app.exec_())

主.qml

import QtQuick 2.13
import QtQuick.Controls 2.13

import TableModel 1.0

ApplicationWindow {
visible: true

Component.onCompleted: {
showMaximized()
}

TableView {
id: tableView
clip: true
anchors.fill: parent
model: TableModel {}
topMargin: columnsHeader.implicitHeight
columnWidthProvider: function () { return tableView.width / tableView.model.columnCount(); }

delegate: Rectangle {
implicitWidth: tableView.columnWidthProvider()
implicitHeight: 40

Text {
text: display
}
}

Row {
id: columnsHeader
y: tableView.contentY
z: 2

Repeater {
model: tableView.columns > 0 ? tableView.columns : 1

Rectangle {
width: tableView.columnWidthProvider()
height: 60
clip: true

Label {
id: headerText
width: parent.width
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: tableView.model.headerData(modelData, Qt.Horizontal)
elide: Text.ElideRight
clip: true
}
}
}
}
}
}

表格模型.py

from typing import Any, Optional

from PySide2.QtCore import QAbstractTableModel, QModelIndex, QObject, Qt

from table import Table


class TableModel(QAbstractTableModel):
def __init__(self, parent: QObject = None) -> None:
super().__init__(parent)
self._model_data = Table(
["This", "Is", "A", "Test", "Of", "Headers"],
[
["A", 1, 2, "B", "C", "D"],
["E", 3, 4, "F", "G", "H"],
["I", 5, 6, "J", "K", "L"],
["M", 7, 8, "N", "O", "P"],
["A", 1, 2, "B", "C", "D"],
["E", 3, 4, "F", "G", "H"],
["I", 5, 6, "J", "K", "L"],
["M", 7, 8, "N", "O", "P"],
["A", 1, 2, "B", "C", "D"],
["E", 3, 4, "F", "G", "H"],
["I", 5, 6, "J", "K", "L"],
["M", 7, 8, "N", "O", "P"],
["A", 1, 2, "B", "C", "D"],
["E", 3, 4, "F", "G", "H"],
["I", 5, 6, "J", "K", "L"],
["M", 7, 8, "N", "O", "P"],
["A", 1, 2, "B", "C", "D"],
["E", 3, 4, "F", "G", "H"],
["I", 5, 6, "J", "K", "L"],
["M", 7, 8, "N", "O", "P"],
["A", 1, 2, "B", "C", "D"],
["E", 3, 4, "F", "G", "H"],
["I", 5, 6, "J", "K", "L"],
["M", 7, 8, "N", "O", "P"],
["A", 1, 2, "B", "C", "D"],
["E", 3, 4, "F", "G", "H"],
["I", 5, 6, "J", "K", "L"],
["M", 7, 8, "N", "O", "P"],
["A", 1, 2, "B", "C", "D"],
["E", 3, 4, "F", "G", "H"],
["I", 5, 6, "J", "K", "L"],
["M", 7, 8, "N", "O", "P"],
["A", 1, 2, "B", "C", "D"],
["E", 3, 4, "F", "G", "H"],
["I", 5, 6, "J", "K", "L"],
["M", 7, 8, "N", "O", "P"],
])

def rowCount(self, parent=QModelIndex()) -> int:
return len(self._model_data.rows)

def columnCount(self, parent=QModelIndex()) -> int:
return len(self._model_data.headers)

def data(self, index: QModelIndex, role=Qt.DisplayRole) -> Optional[Any]:
if role != Qt.DisplayRole:
return None

if not self.checkIndex(index, QAbstractTableModel.CheckIndexOption.IndexIsValid):
return None

return self._model_data.rows[index.row()][index.column()]

def headerData(self, section: int, orientation, role) -> Optional[str]:
if role != Qt.DisplayRole:
return None

if section < 0 or section >= len(self._model_data.headers):
return None

return self._model_data.headers[section]

def reset_with_data(self, model_data: Table) -> None:
self.beginResetModel()
self._model_data = model_data
self.endResetModel()

表格.py


from dataclasses import dataclass
from typing import Any, List


@dataclass
class Table:
headers: List[str]
rows: List[List[Any]]

qml.qrc

<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
</RCC>

运行:

pipenv run pyside2-rcc -o qml_rc.py qml.qrc
pipenv run python main.py

最佳答案

作为the docs指出:

Row heights and column widths

When a new column is flicked into view, TableView will determine its width by calling the columnWidthProvider function. TableView itself will never store row height or column width, as it's designed to support large models containing any number of rows and columns. Instead, it will ask the application whenever it needs to know.

TableView uses the largest implicitWidth among the items as the column width, unless the columnWidthProvider property is explicitly set. Once the column width is found, all other items in the same column are resized to this width, even if new items that are flicked in later have larger implicitWidth. Setting an explicit width on an item is ignored and overwritten.

Note: The calculated width of a column is discarded when it is flicked out of the viewport, and is recalculated if the column is flicked back in. The calculation is always based on the items that are visible when the column is flicked in. This means that it can end up different each time, depending on which row you're at when the column enters. You should therefore have the same implicitWidth for all items in a column, or set columnWidthProvider. The same logic applies for the row height calculation.

If you change the values that a rowHeightProvider or a columnWidthProvider return for rows and columns inside the viewport, you must call forceLayout. This informs TableView that it needs to use the provider functions again to recalculate and update the layout.

Since Qt 5.13, if you want to hide a specific column, you can return 0 from the columnWidthProvider for that column. Likewise, you can return 0 from the rowHeightProvider to hide a row. If you return a negative number, TableView will fall back to calculate the size based on the delegate items.

Note: The size of a row or column should be a whole number to avoid sub-pixel alignment of items.

The following example shows how to set a simple columnWidthProvider together with a timer that modifies the values the function returns. When the array is modified, forceLayout is called to let the changes take effect:

TableView {
id: tableView

property var columnWidths: [100, 50, 80, 150]
columnWidthProvider: function (column) { return columnWidths[column] }

Timer {
running: true
interval: 2000
onTriggered: {
tableView.columnWidths[2] = 150
tableView.forceLayout();
}
}
}

(强调我的)

所以在这种情况下,当 TableView 的宽度发生变化时,您应该调用 forceLayout() .就我而言(Qt 5.13.1、PySide2 5.13.1、Linux)我还必须为 ApplicationWindow 设置宽度和高度:

import QtQuick 2.13
import QtQuick.Controls 2.13

import TableModel 1.0

ApplicationWindow {
visible: true

Component.onCompleted: {
showMaximized()
}

width: 640
height: 480


TableView {
id: tableView
clip: true
anchors.fill: parent
model: TableModel{}
topMargin: columnsHeader.implicitHeight

columnWidthProvider: function (column) {
return tableView.model ? tableView.width/tableView.model.columnCount() : 0
}

onWidthChanged: tableView.forceLayout()

delegate: Rectangle {
implicitWidth: tableView.columnWidthProvider(column)
implicitHeight: 40
Text {
text: display
}
}

Row {
id: columnsHeader
y: tableView.contentY
z: 2
Repeater {
model: tableView.columns > 0 ? tableView.columns : 1
Rectangle {
width: tableView.columnWidthProvider(modelData)
height: 60
clip: true

Label{
id: headerText
width: parent.width
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: tableView.model ? tableView.model.headerData(modelData, Qt.Horizontal): 0
elide: Text.ElideRight
clip: true
}
}
}
}
}
}

关于python - 具有动态宽度列的 QML TableView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57928843/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com