PyQt5中QTableView与QGridLayout的尺寸适配问题
问题描述
开发了一款单行表格输出的GUI程序,采用QGridLayout适配不同系统缩放比例,但遇到问题:将pandas表格加载到QTableView后,表格所在行占用窗口过大空间。尝试过setRowHeight设置最小行高、setRowStretch(0)、调整Table尺寸、设置布局行最小高度等方法均无效。
相关代码片段:
# Table Results self.Table = QTableView() __dfwa = pd.DataFrame() __dfwa['# of Neighbours'] = np.array([None]) __dfwa['Weighted Average Percent Removal [%]'] = np.array([None]) __modelwa = pandasModel(__dfwa) self.Table.setModel(__modelwa) self.Table.horizontalHeader().setSectionResizeMode(0, self.Table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)) self.vbox.addWidget(self.Table, 49,15,1,22) # 布局实例 self.vbox = QGridLayout()
已尝试的无效操作:
self.Table.resize(375, 20)self.vbox.setRowMinimumHeight(49,20)+self.vbox.setRowStretch(49,0)
临时解决方案(效果不完善):
for _i in range(__nRowsMain): if _i == 49: self.vbox.setRowStretch(_i, 1) self.vbox.setRowMinimumHeight(_i, __perH) self.vbox.setRowStretch(_i, 0)
完善解决方案
1. 固定表格行高并隐藏垂直表头
QTableView默认会保留垂直表头的空间,且行高可能随内容自动调整,单行场景下可以直接固定行高并隐藏垂直表头:
# 隐藏垂直表头,消除额外占位 self.Table.verticalHeader().setVisible(False) # 固定单行的高度(数值根据实际UI需求调整) self.Table.setRowHeight(0, 20) # 设置表格垂直方向尺寸策略为固定,禁止自动扩展 self.Table.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
2. 调整布局添加规则
将表格添加到QGridLayout时,指定垂直方向的对齐方式为顶部,并明确设置该行的拉伸因子为0:
# 替换原addWidget代码,添加顶部对齐约束 self.vbox.addWidget(self.Table, 49, 15, 1, 22, alignment=Qt.AlignTop) # 确保该行不分配额外拉伸空间 self.vbox.setRowStretch(49, 0)
3. 限制表格最大高度
直接给QTableView设置最大高度,从根源上防止它占用过多窗口空间:
# 数值根据实际需求调整,比固定行高略大即可 self.Table.setMaximumHeight(30)
4. 检查自定义pandasModel实现
如果你的pandasModel重写了data()或headerData()方法,要确保没有返回影响行高的格式(比如带换行的文本、超大字体)。示例正确实现:
class pandasModel(QAbstractTableModel): def __init__(self, data): super().__init__() self._data = data def data(self, index, role): if role == Qt.DisplayRole: value = self._data.iloc[index.row(), index.column()] # 返回无换行的文本,避免行高被撑开 return str(value) if pd.notna(value) else "" # 不要设置FontRole导致字体过大 return None def rowCount(self, index): return self._data.shape[0] def columnCount(self, index): return self._data.shape[1] def headerData(self, section, orientation, role): if role == Qt.DisplayRole: if orientation == Qt.Horizontal: return str(self._data.columns[section]) return None
组合最优方案
把上述方法结合使用,能彻底解决行高过大的问题:
self.Table = QTableView() __dfwa = pd.DataFrame() __dfwa['# of Neighbours'] = np.array([None]) __dfwa['Weighted Average Percent Removal [%]'] = np.array([None]) __modelwa = pandasModel(__dfwa) self.Table.setModel(__modelwa) # 表格核心配置 self.Table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.Table.verticalHeader().setVisible(False) self.Table.setRowHeight(0, 20) self.Table.setMaximumHeight(30) self.Table.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) # 布局添加规则 self.vbox.addWidget(self.Table, 49, 15, 1, 22, alignment=Qt.AlignTop) self.vbox.setRowStretch(49, 0)
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

