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

如何向QTableWidget添加数千条数据时不冻结窗口

核心问题原因

  • 你当前的同步循环会完全阻塞Qt主事件循环,所有界面更新、用户交互事件都无法被处理,自然会出现窗口无响应
  • QTableWidget默认每次插入行、设置单元格控件的操作都会触发即时重绘,数千次重绘叠加会放大耗时
  • 你之前了解的QThread方案没用是对的,Qt所有界面相关操作都必须在主线程执行,仅把数据准备逻辑放到子线程无法解决问题,耗时大头本身就是界面控件创建和插入操作

可行实现方案(满足不冻结+逐行显示效果)

用QTimer分批插入行,每批插入少量行(可自定义每批数量,比如每次插10~20行),插入完成后主动让出事件循环的执行权,保证主界面可以响应交互、同时渲染刚插入的行。同时在单批插入的过程中临时关闭表格更新,单批插入完成后再打开更新触发一次重绘,进一步降低冗余重绘开销。

优化后代码

import sys
from time import time
from PySide6.QtWidgets import QTableWidget, QPushButton, QHeaderView, QApplication, QMainWindow
from PySide6.QtCore import QTimer

class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setFixedSize(1600, 900)

        self.table = QTableWidget(self)
        self.table.setFixedSize(1600, 900)
        self.table.setColumnCount(5)
        for col in range(5):
            self.table.horizontalHeader().setSectionResizeMode(col, QHeaderView.Stretch)
        self.total_rows = 2000
        self.current_inserted = 0
        self.batch_size = 20 # 可自行调整,数值越大插入越快,界面流畅度越低
        self.insert_timer = QTimer(self)
        self.insert_timer.timeout.connect(self.insert_batch)
        self.show()
        self.insert_timer.start(0) # 0延迟触发,只要事件循环空闲就执行下一批

    def insert_batch(self):
        # 单批插入前关闭更新,避免重复重绘
        self.table.setUpdatesEnabled(False)
        for _ in range(self.batch_size):
            if self.current_inserted >= self.total_rows:
                self.insert_timer.stop()
                self.table.setUpdatesEnabled(True)
                print(f"全部插入完成")
                return
            row = self.table.rowCount()
            self.table.insertRow(row)
            for col in range(5):
                item = QPushButton("filler")
                self.table.setCellWidget(row, col, item)
            self.current_inserted += 1
        # 单批插入完成后打开更新,触发一次重绘
        self.table.setUpdatesEnabled(True)

额外优化建议

  • 如果不需要每个单元格都是独立交互控件,优先使用QTableWidgetItem而不是setCellWidget,性能可以提升数倍
  • 如果后续需要支持更多行数(超过1万行),建议放弃QTableWidget改用QTableView+自定义Model的方案,利用Qt的MVC框架复用渲染控件,只渲染可视区域内的行,性能会有质的提升
  • 可以根据设备性能动态调整batch_size的数值,平衡插入速度和界面流畅度

内容的提问来源于stack exchange,提问作者Campion

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 19:15:01