PySide - PyQt:如何将 QTableWidget 列宽设置为可用 space 的比例?

PySide - PyQt : How to make set QTableWidget column width as proportion of the available space?

我正在使用 PySide 开发计算机应用程序,并且我正在使用 QTableWidget。假设我的 table 有 3 列,但它们包含的数据非常不同,比如(对于每一行)第一列中有一个长句子,然后是最后两列中的 3 位数字。我希望 调整我的 table 大小,以便根据数据 调整其大小,或者至少能够 将列大小设置为(比如说)70/15/15% 的可用 space.

最好的方法是什么?

我在阅读 this question 后尝试了 table.horizontalHeader().setResizeMode(QHeaderView.Stretch),但它使 3 列的大小相同。

由于 Fabio's ,我也尝试了 table.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents),但它没有根据需要填充所有可用的 space。

QHeaderView documentation 中的 InteractiveFixedStretchResizeToContents 似乎都没有给我我需要的东西(见第二次编辑)。

任何帮助将不胜感激,即使是 Qt/C++!非常感谢。


编辑:我找到了一种解决方法,但它仍然不是我要找的东西:

header = table.horizontalHeader()
header.setResizeMode(QHeaderView.ResizeToContents)
header.setStretchLastSection(True)

如果有setStretchFirstSection方法就更好了,可惜好像没有


编辑 2:

table中唯一可以修改的是最后一列,用户可以在其中输入数字。红色箭头表示我想要的。

下面是 Stretch

的情况

这是 ResizeToContents

的情况

您可以使用 QItemDelegatesQStyledItemDelegates 执行此操作。如果你想调整内容 有自动拉伸,你需要选择哪一列是 "stretch" 列。

class ResizeDelegate(QStyledItemDelegate):

    def __init__(self, table, stretch_column, *args, **kwargs):
        super(ResizeDelegate, self).__init__(*args, **kwargs)        
        self.table = table
        self.stretch_column = stretch_column

    def sizeHint(self, option, index):
        size = super(ResizeDelegate, self).sizeHint(option, index)
        if index.column() == self.stretch_column:
            total_width = self.table.viewport().size().width()
            calc_width = size.width()
            for i in range(self.table.columnCount()):
                if i != index.column():
                    option_ = QtGui.QStyleOptionViewItem()
                    index_ = self.table.model().index(index.row(), i)
                    self.initStyleOption(option_, index_)
                    size_ = self.sizeHint(option_, index_)
                    calc_width += size_.width()
            if calc_width < total_width:
                size.setWidth(size.width() + total_width - calc_width)
        return size

...

table = QTableWidget()
delegate = ResizeDelegate(table, 0)
table.setItemDelegate(delegate)
... # Add items to table
table.resizeColumnsToContents()

您可以将调整大小模式设置为ResizeToContents,或者如果您希望用户能够根据需要调整列宽,只需在更改[=]后手动调用resizeColumnsToContents 25=] 项。

由于列之间的边距和填充,您可能还需要稍微修改一下宽度计算(比如为每列向 calculated_width 添加一两个像素以考虑单元格边框)。

这可以通过为每列设置调整大小模式来解决。第一部分必须拉伸以占用可用的 space,而最后两部分只需根据其内容调整大小:

PyQt4:

header = self.table.horizontalHeader()
header.setResizeMode(0, QtGui.QHeaderView.Stretch)
header.setResizeMode(1, QtGui.QHeaderView.ResizeToContents)
header.setResizeMode(2, QtGui.QHeaderView.ResizeToContents)

PyQt5:

header = self.table.horizontalHeader()       
header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents)
header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents)

PyQt4

header = self.table.horizontalHeader()
header.setResizeMode(0, QtGui.QHeaderView.Stretch)
header.setResizeMode(1, QtGui.QHeaderView.ResizeToContents)
header.setResizeMode(2, QtGui.QHeaderView.ResizeToContents)
header.setResizeMode(3, QtGui.QHeaderView.Stretch)

PyQt5

header = self.table.horizontalHeader()       
header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents)
header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents)
header.setSectionResizeMode(3, QtWidgets.QHeaderView.Stretch)

如前所述,您可以通过设置每列的调整大小模式来实现。但是,如果您有很多列,这可能是很多代码。我这样做的方法是将 "general" resize-mode 设置为 "ResizeToContent" 而不是将一个(或多个)列设置为 "Stretch"!

代码如下:

PyQt4:

header = self.table.horizontalHeader()
header.setResizeMode(QtGui.QHeaderView.ResizeToContents)
header.setResizeMode(0, QtGui.QHeaderView.Stretch)

PyQt5:

header = self.table.horizontalHeader()
header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)       
header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)

我用过这个,setMinumumsectionsize解决了我的Qtableview cell size的问题

self.questionWidget.tableView.setModel(self.model)
self.questionWidget.tableView.verticalHeader().setVisible(False)
self.questionWidget.tableView.horizontalHeader().setMinimumSectionSize(200)

我必须删除 QtWidget 才能让我的工作。

        header = self.tag_table.horizontalHeader()
        header.setSectionResizeMode(QHeaderView.ResizeToContents)

这在 PyQt5 中对我有用:

table_name.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)

它会自动调整所有列的大小。

这是我所有的横向 header 设置:

    table_name.horizontalHeader().setVisible(True)
    table_name.horizontalHeader().setCascadingSectionResizes(True)
    table_name.horizontalHeader().setDefaultSectionSize(140)
    table_name.horizontalHeader().setHighlightSections(False)
    table_name.horizontalHeader().setMinimumSectionSize(100)
    table_name.horizontalHeader().setSortIndicatorShown(False)
    table_name.horizontalHeader().setStretchLastSection(False)
   table_name.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)