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

问题描述 投票:0回答:11

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

最好的方法是什么?

阅读完

这个问题
后,我尝试过table.horizontalHeader().setResizeMode(QHeaderView.Stretch),但它使 3 列大小相同。

我也尝试过

table.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
,感谢Fabio评论,但它并没有根据需要填充所有可用空间。

QHeaderView文档

中的
Interactive
Fixed
Stretch
ResizeToContents似乎都没有给我我需要的东西(参见第二次编辑)。

任何帮助将不胜感激,即使是针对

Qt/C++!非常感谢。


编辑:我找到了一种解决方法,但它仍然不是我正在寻找的:

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

如果有一个

setStretchFirstSection

的方法就更好了,可惜好像没有。


编辑2:

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

这就是

Stretch

 发生的情况

这就是

ResizeToContents

 
发生的情况

python user-interface pyqt pyside qtablewidget
11个回答
99
投票
这可以通过为每列设置

resize-mode 来解决。第一部分必须拉伸以占据可用空间,而最后两部分只需调整其大小以适应其内容:

PyQt5:

header = self.table.horizontalHeader() header.setSectionResizeMode(0, QHeaderView.Stretch) header.setSectionResizeMode(1, QHeaderView.ResizeToContents) header.setSectionResizeMode(2, QHeaderView.ResizeToContents)
PyQt6/PyQt5:

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

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

14
投票
如前所述,您可以通过设置每列的调整大小模式来做到这一点。但是,如果您有很多列,则可能会需要很多代码。我这样做的方法是将“常规”调整大小模式设置为“ResizeToContent”,并将一列(或多列)设置为“拉伸”!

这是代码:

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)
    

5
投票
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)
    

4
投票
我已经使用了这个并且setMinumumsectionsize解决了我的Qtableview单元格大小问题

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

3
投票
您可以使用

QItemDelegates

QStyledItemDelegates
 来完成此操作。如果您想调整内容大小
并且具有自动拉伸,您需要选择哪一列是“拉伸”列。

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
即可。

由于列之间的边距和填充,您可能还需要稍微修改宽度计算(例如在每列的

calculated_width

 中添加一两个像素以考虑单元格边框)。


2
投票
我必须删除 QtWidget 才能让我的 QtWidget 正常工作。

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

1
投票
PyQt6

header = self.table.horizontalHeader() header.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeMode.Stretch) header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeMode.ResizeToContents) header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeMode.ResizeToContents)
调整大小选项是类型的枚举 

ResizeMode

 
其他可用选项是

Interactive = ... # type: QHeaderView.ResizeMode Fixed = ... # type: QHeaderView.ResizeMode Stretch = ... # type: QHeaderView.ResizeMode ResizeToContents = ... # type: QHeaderView.ResizeMode Custom = ... # type: QHeaderView.ResizeMode
    

0
投票

这在 PyQt5 中对我有用:

table_name.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
它将自动调整所有列的大小。

这是我所有的水平标题设置:

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)
    

0
投票
在继承自

QTableWidget的类中,我在PyQt5中实现了这个功能:

def set_header_stretch_first_section(self): header = self.horizontalHeader() header.setSectionResizeMode(0, QHeaderView.Stretch) for i in range(1, self.columnCount()): header.setSectionResizeMode(i, QHeaderView.ResizeToContents)
    

0
投票
我无法找到“开箱即用”的解决方案,但我做了以下操作:

创建一个线程,检查表的大小是否每 50 毫秒更改一次,如果更改,则触发一个信号到槽,该槽根据当前表的大小更新列宽。

在下面的示例中,列宽的比例为 1:1:2。

示例:

import time from PySide6.QtCore import Signal # Class definition here def __init__(self): # Class initialization here self.signal_table_size_changed = Signal() self.signal_table_size_changed.connect(self.adjust_table_column_width) self.table_width = None threading.Thread(target=self.table_size_watcher).start() def adjust_table_column_width(self): self.table_width = self.table.size().width() self.table.setColumnWidth(0, 0.25 * self.table_width) self.table.setColumnWidth(1, 0.25 * self.table_width) self.table.setColumnWidth(2, 0.50 * self.table_width) def table_size_watcher(self): while True: if self.table_width != self.table.size().width(): self.signal_table_size_changed.emit() time.sleep(0.05)
    

0
投票
在 PySide6 中修复 QTableView 中的 5 列之前 会延伸到可见的桌子之外

修复后,它们完美对齐 (顺便说一句,表格视图的固定宽度为 371px) (也使用 QtDesigner)

self.table_view = QTableView() self.model.setHeaderData(index,Qt.Horizontal,value) self.table_view.setColumnWidth(0,65) #(index,width-px) self.table_view.setColumnWidth(1,75) self.table_view.setColumnWidth(2,75) self.table_view.setColumnWidth(3,75) self.table_view.setColumnWidth(4,71)
屏幕截图(绿屏右下角):

© www.soinside.com 2019 - 2024. All rights reserved.