PyQt5点击RadioButton时GUI崩溃:如何正常显示过滤后DataFrame
问题修复方案
崩溃原因分析
- 信号参数不匹配:
QRadioButton.toggled信号会自动传递一个布尔值(表示是否被选中),但绑定的Selected_Values方法需要两个参数,而原代码的lambda只传了一个参数,参数数量不匹配触发崩溃。 - 未更新GUI显示:原代码仅打印过滤后的DataFrame,没有将新数据同步到
QTableView的模型中,无法实现界面刷新。 - QMainWindow布局错误:直接对
QMainWindow调用setLayout不符合规范,应该将布局设置到centralwidget上。
具体修复步骤
- 修正信号绑定,正确传递
toggled信号的布尔值参数 - 实现模型更新逻辑,过滤数据后重新创建模型并绑定到
QTableView - 修复布局结构,将布局应用到
centralwidget - 保存原始DataFrame副本,支持取消过滤时恢复初始数据
完整修复代码
from PyQt5.QtCore import Qt, QSize, QAbstractTableModel import os import pandas as pd import numpy as np import sys from PyQt5 import QtGui, QtCore from PyQt5.QtWidgets import (QMainWindow, QPushButton, QListWidget, QPlainTextEdit, QScrollBar, QWidget, QCheckBox, QHBoxLayout, QApplication, QSizePolicy, QVBoxLayout, QScrollArea, QTableView, QTextEdit, QRadioButton) pd.set_option('display.max_columns', 25) pd.set_option('display.width', 2000) class MainWindow(QMainWindow): def __init__(self, parent = None): super().__init__(parent) self.setWindowTitle('Test GUI') self.setGeometry(0, 0, 1200, 650) self.CoreFunctionality() def Selected_Values(self, selected): if selected: # 基于C列值过滤数据 filtered_df = self.original_df.loc[self.original_df['C'] == 50] # 更新TableView模型 self.model = PandasTableModel(filtered_df) self.pdtable.setModel(self.model) self.pdtable.resizeColumnsToContents() else: # 恢复原始数据显示 self.model = PandasTableModel(self.original_df) self.pdtable.setModel(self.model) self.pdtable.resizeColumnsToContents() def CoreFunctionality(self): self.centralwidget = QWidget(self) self.setCentralWidget(self.centralwidget) main_layout = QVBoxLayout(self.centralwidget) hbox = QHBoxLayout() hbox.addStretch(1) # 保存原始DataFrame副本 self.original_df = pd.DataFrame(np.random.randint(0, 100, size=(100, 4)), columns=list('ABCD')) self.pdtable = QTableView() self.model = PandasTableModel(self.original_df) self.pdtable.setModel(self.model) self.pdtable.setShowGrid(False) self.pdtable.resizeColumnsToContents() hbox.addWidget(self.pdtable) # 创建单选按钮并正确绑定信号 filter_radio = QRadioButton('Filter Button') filter_radio.toggled.connect(self.Selected_Values) main_layout.addWidget(filter_radio) main_layout.addLayout(hbox) self.pdtable.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) class PandasTableModel(QtGui.QStandardItemModel): def __init__(self, data, parent=None): super().__init__(parent) self._data = data # 填充表格数据 for col_idx, col in enumerate(data.columns): data_col = [QtGui.QStandardItem(f"{x}") for x in data[col].values] self.appendColumn(data_col) def rowCount(self, parent=None): return len(self._data) def columnCount(self, parent=None): return self._data.shape[1] def headerData(self, section, orientation, role): if orientation == Qt.Horizontal and role == Qt.DisplayRole: return self._data.columns[section] if orientation == Qt.Vertical and role == Qt.DisplayRole: return self._data.index[section] return None if (__name__ == '__main__'): application = QApplication(sys.argv) main_window = MainWindow() main_window.show() application.exec()
额外优化说明
- 将pandas导入别名改为通用的
pd,避免与变量名混淆 - 优化模型的行列数计算逻辑,使用DataFrame内置属性更可靠
- 调整布局结构,让表格控件可以自适应窗口大小变化
内容的提问来源于stack exchange,提问作者acm151130
相关产品推荐
相关产品推荐

