You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 11:42:52