I am trying to set up a simple QTreeView with nice columns. The first two columns are set to fit the contents, the last column is set to stretch.
For some reason, the minimum width of the last column ("Balance") is way higher than it needs to be, which produces unwanted behaviour. I captured this behavior on this video (YouTube link). The last column takes way too much space and does not shrink as much as it should when the QWidget is shrunk.
The complete code producing this example is below. I am aware the QAbstractItemModel is implemented incorrectly but it is a minimal implementation that showcases the issue.
I tried playing around with QTreeView.header().setMinimumWidth(0)
but that did not work either.
I don't understand where is the issue because I think the MRE below is already very barebones and nearly all settings are left to default values. Why would the column which has ResizeMode.Stretch need to take up so much minimum width? Shouldn't it take at maximum the width of the header text, i.e. "Balance"? It seems to take up roughly twice as much.
I am running Python 3.11.2 and PyQt 6.4.2.
MRE:
import sys
from typing import Any
from PyQt6 import QtWidgets
from PyQt6.QtCore import QAbstractItemModel, QModelIndex, Qt
from PyQt6.QtWidgets import QApplication, QHeaderView, QTreeView, QWidget
class Form(QWidget):
def __init__(self, parent: QWidget | None = None) -> None:
super().__init__(parent=parent)
self.resize(323, 454)
self.horizontalLayout = QtWidgets.QHBoxLayout(self)
self.horizontalLayout.setObjectName("horizontalLayout")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout.addLayout(self.verticalLayout)
self.treeView = QTreeView(self)
self.verticalLayout.addWidget(self.treeView)
self.treeView.setModel(CategoryTreeModel(self.treeView))
self.treeView.header().setSectionResizeMode(
0,
QHeaderView.ResizeMode.ResizeToContents,
)
self.treeView.header().setSectionResizeMode(
1,
QHeaderView.ResizeMode.ResizeToContents,
)
self.treeView.header().setSectionResizeMode(
2,
QHeaderView.ResizeMode.Stretch,
)
class CategoryTreeModel(QAbstractItemModel):
COLUMN_HEADERS = {
0: "Name",
1: "Transactions",
2: "Balance",
}
def __init__(
self,
tree_view: QTreeView,
) -> None:
super().__init__()
self._tree_view = tree_view
def rowCount(self, index: QModelIndex = ...) -> int:
return 5
def columnCount(self, index: QModelIndex = ...) -> int: # noqa: U100
return 3
def index(self, row: int, column: int, _parent: QModelIndex = ...) -> QModelIndex:
return QAbstractItemModel.createIndex(self, row, column, "item")
def parent(self, index: QModelIndex = ...) -> QModelIndex:
return QModelIndex()
def data(self, index: QModelIndex, role: Qt.ItemDataRole = ...) -> Any:
if not index.isValid():
return None
column = index.column()
if role == Qt.ItemDataRole.DisplayRole:
if column == 0:
return "some very long name"
if column == 1:
return "0"
if column == 2:
return "0"
return None
def headerData(
self, section: int, orientation: Qt.Orientation, role: Qt.ItemDataRole = ...
) -> str | int | None:
if role == Qt.ItemDataRole.TextAlignmentRole:
if section == 2:
return Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter
if role == Qt.ItemDataRole.DisplayRole:
if orientation == Qt.Orientation.Horizontal:
return self.COLUMN_HEADERS[section]
return str(section)
return None
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec()
source https://stackoverflow.com/questions/75429501/qtreeview-column-header-width-is-too-large
Comments
Post a Comment