如何在Qt标签页中动态创建并填充QTableWidget?
Qt动态生成QTableWidget布局问题修复
问题核心
刷新数据生成新标签页时,多个QTableWidget要么堆叠重叠,要么添加布局代码后完全不显示。根源是布局未绑定到窗口、表格初始化参数错误、表头格式化逻辑错误、标签页删除逻辑bug这几个问题导致的。
修复要点
- 给MyTab绑定布局:创建QGridLayout后必须调用
self.setLayout(self.layout),否则布局不会生效,表格自然无法显示。 - 修正QTableWidget初始化参数:原代码
QtWidgets.QTableWidget(i, 0)会让第i个表格行数为i,改用QtWidgets.QTableWidget()初始化空表格,后续通过setRowCount和setColumnCount设置行列数更稳妥。 - 表头格式化逻辑修正:
headerComponents是字符串列表,用'{:.2f}'.format(x)会报错,直接用原列表设置表头即可。 - 标签页删除逻辑修正:正序删除标签页时,
tabManager.count()会动态变化导致漏删,改成倒序删除即可。
修改后的完整代码
主窗口类代码
class MyQtApp(main.Ui_MainWindow, QtWidgets.QMainWindow): def __init__(self): super(MyQtApp, self).__init__() self.setupUi(self) self.qDashboard_refreshdata_btn.clicked.connect(self.refresh_data) def refresh_data(self): # 刷新时移除除Dashboard外的所有标签页,倒序删除避免漏删 while self.tabManager.count() > 1: self.tabManager.removeTab(1) tabName = 'abc' d1 = {'col1': [1, 2], 'col2': [3, 4], 'col3': [1, 2], 'col4': [3, 4]} df1 = pd.DataFrame(data=d1) d2 = {'col1': [5, 6], 'col2': [7, 8], 'col3': [9, 2], 'col4': [78, 4]} df2 = pd.DataFrame(data=d2) df_list = [df1, df2] # 表头长度需和DataFrame列数匹配,原代码列数为4,这里修正表头数量 header_label = ['My first Column', 'My second Column', 'My third Column', 'My fourth Column'] self.addingTab = MyTab(df_list, len(df_list), header_label) self.tabManager.addTab(self.addingTab, tabName)
自定义标签页类代码
class MyTab(QtWidgets.QWidget): def __init__(self, listData, nbComponents, headerComponents, parent=None): super().__init__(parent) self.layout = QtWidgets.QGridLayout() self.Table = [] for i in range(nbComponents): # 初始化空表格,后续设置行列数 self.Table.append(QtWidgets.QTableWidget()) self.Table[i].setObjectName("table_" + str(i)) self.Table[i].setColumnCount(len(headerComponents)) # 直接使用原表头列表,无需格式化字符串 self.Table[i].setHorizontalHeaderLabels(headerComponents) self.Table[i].setRowCount(len(listData[i])) self.loaddata(listData[i], self.Table[i]) # 将表格添加到布局的第i行第0列 self.layout.addWidget(self.Table[i], i, 0) # 关键步骤:将布局绑定到当前QWidget self.setLayout(self.layout) def loaddata(self, df, tableNb): for x in range(len(df)): for y in range(tableNb.columnCount()): tableNb.setItem(x, y, QtWidgets.QTableWidgetItem(str(df.iloc[x, y])))
额外提示
- 确保
header_label长度与DataFrame列数一致,否则表头会显示不全。 - 如果表格内容过多,可给每个QTableWidget添加滚动条优化体验:
self.Table[i].setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
内容的提问来源于stack exchange,提问作者Hotone
相关产品推荐
相关产品推荐

