QTableWidget设置setStretchLastSection致窗口缩放时水平滚动条消失问题
修复QTableWidget窗口缩放时自动换行与滚动条消失问题
问题代码
def fill_table(self): self.tableWidget = QTableWidget(self.view_frame) self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) self.tableWidget.setAlternatingRowColors(True) self.tableWidget.setFocusPolicy(Qt.NoFocus) self.tableWidget.setShowGrid(False) self.tableWidget.setSortingEnabled(True) self.tableWidget.horizontalHeader().setHighlightSections(False) self.tableWidget.horizontalHeader().setProperty("showSortIndicator", True) self.tableWidget.horizontalHeader().setStretchLastSection(True) self.tableWidget.verticalHeader().setVisible(False) self.tableWidget.verticalHeader().setHighlightSections(False) self.ui.tableWidget.setRowCount(0) self.ui.tableWidget.setColumnCount(6) self.ui.tableWidget.setRowCount(len(self.zipped_log)) self.ui.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows) self.ui.tableWidget.setSelectionMode(QAbstractItemView.SingleSelection) self.ui.tableWidget.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) self.ui.tableWidget.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel) self.ui.tableWidget.setFocusPolicy(Qt.NoFocus) for i in range(len(self.zipped_log)): self.ui.tableWidget.setItem(i, 0, QTableWidgetItem(str(self.zipped_log[i]['date']))) self.ui.tableWidget.setItem(i, 1, QTableWidgetItem(str(self.zipped_log[i]['time']))) self.ui.tableWidget.setItem(i, 2, QTableWidgetItem(self.zipped_log[i]['source'])) self.ui.tableWidget.setItem(i, 3, QTableWidgetItem(self.zipped_log[i]['code'])) self.ui.tableWidget.setItem(i, 4, QTableWidgetItem(str(self.zipped_log[i]['severity']))) self.ui.tableWidget.setItem(i, 5, QTableWidgetItem(self.zipped_log[i]['description'])) self.ui.tableWidget.resizeColumnsToContents() self.ui.tableWidget.resizeRowsToContents() self.ui.tableWidget.horizontalHeader().setStretchLastSection(True) def resizeEvent(self, event): self.ui.tableWidget.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.ui.tableWidget.setWordWrap(False) QMainWindow.resizeEvent(self, event)
问题现象
- 初始填充短内容时,内容适配窗口尺寸,无异常;
- 重新填充超出窗口尺寸的长内容时,水平滚动条正常激活,可横向滚动;
- 缩放窗口后,长内容自动换行,水平滚动条消失,内容末尾显示省略号
...。
解决方案
问题核心在于setStretchLastSection(True)的强制拉伸逻辑会挤压列宽触发换行,同时存在对象引用混淆、换行属性未全局生效的问题,具体修复步骤如下:
1. 统一对象引用
代码中同时使用self.tableWidget(手动创建)和self.ui.tableWidget(UI文件对象),导致设置失效,需统一使用同一个对象,以下示例统一用手动创建的self.tableWidget。
2. 全局禁用换行
在表格初始化和单元格创建时,都明确禁用换行:
# 表格初始化时全局禁用换行 self.tableWidget.setWordWrap(False) # 表头也禁用换行 self.tableWidget.horizontalHeader().setWordWrap(False) # 填充单元格时给每个item禁用换行 item_desc = QTableWidgetItem(log['description']) item_desc.setWordWrap(False) self.tableWidget.setItem(i, 5, item_desc)
3. 动态调整最后一列拉伸策略
移除固定的setStretchLastSection(True),改为根据总列宽和窗口宽度的关系动态切换:
# 填充内容后执行 self.tableWidget.resizeColumnsToContents() total_col_width = sum(self.tableWidget.columnWidth(col) for col in range(6)) if total_col_width < self.tableWidget.viewport().width(): self.tableWidget.horizontalHeader().setStretchLastSection(True) else: self.tableWidget.horizontalHeader().setStretchLastSection(False)
4. 修正resizeEvent逻辑
窗口缩放时重新计算列宽,调整拉伸策略并刷新列宽:
def resizeEvent(self, event): self.tableWidget.setWordWrap(False) header = self.tableWidget.horizontalHeader() total_col_width = sum(self.tableWidget.columnWidth(col) for col in range(self.tableWidget.columnCount())) if total_col_width < self.tableWidget.viewport().width(): header.setStretchLastSection(True) else: header.setStretchLastSection(False) # 强制刷新列宽,避免窗口缩放挤压内容 self.tableWidget.resizeColumnsToContents() QMainWindow.resizeEvent(self, event)
最终修改后的关键代码片段
def fill_table(self): self.tableWidget = QTableWidget(self.view_frame) self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) self.tableWidget.setAlternatingRowColors(True) self.tableWidget.setFocusPolicy(Qt.NoFocus) self.tableWidget.setShowGrid(False) self.tableWidget.setSortingEnabled(True) self.tableWidget.setWordWrap(False) self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows) self.tableWidget.setSelectionMode(QAbstractItemView.SingleSelection) self.tableWidget.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) self.tableWidget.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel) # 表头设置 header = self.tableWidget.horizontalHeader() header.setHighlightSections(False) header.setProperty("showSortIndicator", True) header.setWordWrap(False) self.tableWidget.verticalHeader().setVisible(False) self.tableWidget.verticalHeader().setHighlightSections(False) # 设置列数和行数 self.tableWidget.setColumnCount(6) self.tableWidget.setRowCount(len(self.zipped_log)) # 填充数据 for i in range(len(self.zipped_log)): log = self.zipped_log[i] # 逐个创建item并禁用换行 item_date = QTableWidgetItem(str(log['date'])) item_date.setWordWrap(False) self.tableWidget.setItem(i, 0, item_date) item_time = QTableWidgetItem(str(log['time'])) item_time.setWordWrap(False) self.tableWidget.setItem(i, 1, item_time) item_source = QTableWidgetItem(log['source']) item_source.setWordWrap(False) self.tableWidget.setItem(i, 2, item_source) item_code = QTableWidgetItem(log['code']) item_code.setWordWrap(False) self.tableWidget.setItem(i, 3, item_code) item_severity = QTableWidgetItem(str(log['severity'])) item_severity.setWordWrap(False) self.tableWidget.setItem(i, 4, item_severity) item_desc = QTableWidgetItem(log['description']) item_desc.setWordWrap(False) self.tableWidget.setItem(i, 5, item_desc) # 动态调整列宽与拉伸策略 self.tableWidget.resizeColumnsToContents() self.tableWidget.resizeRowsToContents() total_col_width = sum(self.tableWidget.columnWidth(col) for col in range(6)) if total_col_width < self.tableWidget.viewport().width(): header.setStretchLastSection(True) else: header.setStretchLastSection(False) def resizeEvent(self, event): self.tableWidget.setWordWrap(False) header = self.tableWidget.horizontalHeader() total_col_width = sum(self.tableWidget.columnWidth(col) for col in range(self.tableWidget.columnCount())) if total_col_width < self.tableWidget.viewport().width(): header.setStretchLastSection(True) else: header.setStretchLastSection(False) self.tableWidget.resizeColumnsToContents() QMainWindow.resizeEvent(self, event)
内容的提问来源于stack exchange,提问作者MIku
相关产品推荐
相关产品推荐

