如何设置QMainWindow尺寸以适配带自定义垂直表头的QTableWidget
问题根因
设置垂直表头标签后,表头的尺寸计算会产生延迟,__init__阶段执行的列宽行高适配、sizeHint计算拿到的都是未更新垂直表头尺寸的旧值,最终导致主窗口适配尺寸偏小,出现滚动条。同时原有代码中循环变量m被覆盖,导致垂直表头数量设置也存在误差。
解决方案
你可以通过延迟触发尺寸适配、调整主窗口尺寸设置时机解决问题,修改后的可运行代码如下:
from PyQt5.QtWidgets import QApplication, QTableWidget, QTableWidgetItem, QMainWindow from PyQt5.QtCore import QSize, QTimer, Qt import sys DATA = { f'col{i}': [f'{i * j}' for j in range(1, 10)] for i in range(1, 10) } class Table(QTableWidget): def __init__(self, d): row_count = len(d[next(iter(d))]) col_count = len(DATA) super().__init__(row_count, col_count) hor_headers = [] for col_idx, (key, values) in enumerate(DATA.items()): hor_headers.append(key) for row_idx, item in enumerate(values): qtitem = QTableWidgetItem(item) self.setItem(row_idx, col_idx, qtitem) self.setHorizontalHeaderLabels(hor_headers) # 保留垂直表头设置,修正变量覆盖问题 self.setVerticalHeaderLabels(f'row{i}' for i in range(1, self.rowCount() + 1)) # 延迟触发表格尺寸适配,等表头渲染完成 QTimer.singleShot(0, self.adjust_table_size) def adjust_table_size(self): self.resizeColumnsToContents() self.resizeRowsToContents() # 关闭滚动条自动显示,避免尺寸计算时滚动条占用空间导致误差 self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) def sizeHint(self): hh = self.horizontalHeader() vh = self.verticalHeader() fw = self.frameWidth() * 2 return QSize( hh.length() + vh.width() + fw, vh.length() + hh.height() + fw) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle('<TITLE>') self.table = Table(DATA) self.setCentralWidget(self.table) # 等表格尺寸计算完成后设置主窗口固定尺寸 QTimer.singleShot(0, self.adjust_window_size) def adjust_window_size(self): self.setFixedSize(self.table.sizeHint()) def main(args): app = QApplication(args) main_win = MainWindow() main_win.show() raise SystemExit(app.exec_()) if __name__ == "__main__": main(sys.argv)
关键修改说明
- 用
QTimer.singleShot(0, 回调)把尺寸适配逻辑放到Qt事件循环的空闲阶段执行,确保拿到的垂直表头、列宽、行高都是最终渲染后的准确值 - 显式关闭表格的滚动条自动显示,避免尺寸计算时滚动条占用空间产生误差
- 修正了循环变量覆盖导致的垂直表头数量设置错误问题
- 把主窗口的尺寸设置放到表格尺寸计算完成后执行,确保拿到的sizeHint是正确值
内容的提问来源于stack exchange,提问作者AXO
相关产品推荐
相关产品推荐

