我正在使用 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
发生的情况
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)
这是代码:
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)
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)
self.questionWidget.tableView.setModel(self.model)
self.questionWidget.tableView.verticalHeader().setVisible(False)
self.questionWidget.tableView.horizontalHeader().setMinimumSectionSize(200)
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
中添加一两个像素以考虑单元格边框)。
header = self.tag_table.horizontalHeader()
header.setSectionResizeMode(QHeaderView.ResizeToContents)
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
这在 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)
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)
创建一个线程,检查表的大小是否每 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)
修复后,它们完美对齐 (顺便说一句,表格视图的固定宽度为 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)
屏幕截图(绿屏右下角):