下面的示例(PySide,使用QT 4.8)将按比例将列宽更改为QTableView的宽度。当用户手动调整列的宽度时(双击或拖动节标题),从那时起,该特定列的宽度将保持不变,而其他列将按比例填充剩余空间。
from PySide.QtGui import *
from PySide.QtCore import QEvent
class CustomTableView(QTableView):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.verticalHeader().hide()
self.horizontalHeader().sectionResized.connect(self.section_resized)
self.dynamically_resized = False
self.fixed_section_widths = dict()
@disconnect_section_resized
def dynamic_column_resize(self):
flexible_width = self.width() - 2 - sum(self.fixed_section_widths.values())
column_count = self.model().columnCount()
flexible_column_count = column_count - len(self.fixed_section_widths)
column_width = flexible_width // flexible_column_count if flexible_column_count else 1
last_flexible_column_width = column_width + flexible_width % column_width
for column_index in range(column_count):
if column_index not in self.fixed_section_widths:
width = column_width if flexible_column_count > 1 else last_flexible_column_width
flexible_column_count = flexible_column_count - 1
else:
width = self.fixed_section_widths[column_index]
self.setColumnWidth(column_index, width)
self.dynamically_resized = True
def section_resized(self, column_index, old_size, new_size):
if not self.dynamically_resized:
return
self.fixed_section_widths[column_index] = self.columnWidth(column_index)
self.dynamic_column_resize()
def eventFilter(self, obj, event):
if event.type() == QEvent.Resize:
self.dynamic_column_resize()
return True
return super(QTableView, self).eventFilter(obj, event)
这个
section_resized
方法旨在为某一列应用固定宽度,只应在以下情况下运行
sectionResized
信号已由(手动)用户交互发出。这个
dynamic_column_resize
方法(每次
QTableWidget
更改宽度)不应触发
section\u已调整大小
方法,因为这样会有一个无限循环,因为在
section\u已调整大小
这个
dynamic\u column\u resize动态调整列大小
方法被调用。以下装饰器用于防止出现这种情况:
def disconnect_section_resized(func):
def wrapper(self):
self.horizontalHeader().sectionResized.disconnect(self.section_resized)
func(self)
self.horizontalHeader().sectionResized.connect(self.section_resized)
return wrapper