【问题标题】:Why the width of the columns in the tableView does not change为什么tableView中列的宽度没有变化
【发布时间】:2019-06-18 23:26:21
【问题描述】:

我正在编写第一个模型。

我不能改变列标题的宽度,但是高度会改变!

标题宽度不起作用。 标题的高度有效。

最小的可重现示例

import sys
from PyQt5 import QtCore
from PyQt5 import QtWidgets


class QModelTable(QtCore.QAbstractTableModel):

    def __init__(self, data_list):
        super().__init__()
        self.data_list = data_list

    def columnCount(self, parent=None, *args, **kwargs):
        return len(self.data_list[0])

    def rowCount(self, parent=None, *args, **kwargs):
        return len(self.data_list)

    def data(self, index, role=None):
        if not index.isValid():
            return None

        row = index.row()
        col = index.column()

        if role == QtCore.Qt.DisplayRole:
            return self.data_list[row][col]

    def headerData(self, section, orientation, role=None):

        if role == QtCore.Qt.SizeHintRole:
            if orientation == QtCore.Qt.Horizontal:
                # I want a column width of 40px
                return QtCore.QSize(40, 40)  # The problem is here


test_data = (
    ('row 1 col 1', 'row 1 col 2', 'row 1 col 3'),
    ('row 2 col 1', 'row 2 col 2', 'row 2 col 3'),
    ('row 3 col 1', 'row 3 col 2', 'row 3 col 3'),
)


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

    model = QModelTable(test_data)
    table = QtWidgets.QTableView()
    table.setModel(model)

    table.show()

    sys.exit(app.exec_())

结果如下:

【问题讨论】:

  • 我加了一个例子
  • @АлександрРублев SizeHintRole 仅用于计算每列的 sizeHint,在本例中为 40,即小部件将尝试建立该大小如果可能,也就是说,它是理想的,但受制于其他因素,例如:文本的大小,是否建立了固定大小等。例如,如果您减小宽度,您将看到最小宽度为 40。
  • @eyllanesc 认为事实并非如此。如果我想将列宽设置为 200px,它也不起作用。
  • @АлександрРублев 正如我告诉你的那样,它把它作为参考,但它没有明确使用它,QHeaderView 取决于 ResizeMode 建立使用大小。

标签: python pyqt pyqt5


【解决方案1】:

您的问题有不同的解决方案。最简单有效的方法是为您想要“固定”大小的列使用通用项目委托,然后将其 resizeMode 设置为 ResizeToContents

class FixedColumnDelegate(QtWidgets.QStyledItemDelegate):
    def __init__(self, defaultWidth=None, parent=None):
        QtWidgets.QStyledItemDelegate.__init__(self, parent)
        self.defaultWidth = defaultWidth

    def sizeHint(self, option, index):
        hint = QtWidgets.QStyledItemDelegate.sizeHint(self, option, index)
        if self.defaultWidth is not None:
            hint.setWidth(self.defaultWidth)
        return hint

    [...]

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

    model = QModelTable(test_data)
    table = QtWidgets.QTableView()
    table.setModel(model)
    table.setItemDelegateForColumn(2, FixedColumnDelegate(40, table))
    table.horizontalHeader().setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents)

    table.show()

    sys.exit(app.exec_())

请记住,至少对于 PyQt,如果您需要的项目视图不只是一个项目委托,您总是需要设置其父级或确保委托的实例作为对象属性保持持久性(无论如何对象是,只要确保它不会在主类声明的末尾或声明它时出现在垃圾收集器上),否则您将面临一些意外且可能难以调试的行为:设置项目委托“on苍蝇”(如 setItemDelegate*() 函数中的实例声明)总是会在您在视图中设置多个委托时产生问题。

【讨论】:

    【解决方案2】:

    如果您查看此问题及其解决方案,可能会给您一个不同的想法,也许您可​​以得到一些关于您可能没有考虑过的事情的煽动

    How to auto stretch QTableView columns and keep them being adjustable

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-20
      • 1970-01-01
      • 2016-09-14
      • 1970-01-01
      • 1970-01-01
      • 2017-11-01
      • 1970-01-01
      • 2016-02-05
      相关资源
      最近更新 更多