为什么tableView中列的宽度不改变

时间:2019-06-17 16:38:13

标签: python pyqt pyqt5

我正在写第一个模型。

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

页眉宽度不起作用。 标头的高度有效。

enter image description here

最小可重复示例

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_())

结果如下: enter image description here

2 个答案:

答案 0 :(得分: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而言,如果您需要一个项目视图不止一个项目委托,则始终需要设置其父项或确保将委托的实例作为对象属性保持不变(无论那是什么)对象是,只需确保它不会在主类声明的末尾或在声明它的任何时候结束在垃圾收集器上),否则您将面临一些意外的且可能难以调试的行为:将项目委托设置为“每当您在一个视图中设置多个委托时,“ fly”(就像setItemDelegate *()函数中的实例声明一样)总是会产生问题。

答案 1 :(得分:1)

如果您着眼于这个问题及其解决方案,可以给您一个不同的想法,也许您会激起一些您可能未曾考虑过的事情

How to auto stretch QTableView columns and keep them being adjustable