Kivy调用pandasgui后界面冻结,求线程解决方法
解决Kivy调用pandasgui后界面冻结的问题
问题根源在于pandasgui.show()会启动一个基于Tkinter的GUI界面,而Kivy的界面渲染依赖主线程,当你在Kivy主线程中调用show(df)时,会阻塞主线程,导致返回Kivy界面时程序冻结。用线程将数据处理和pandasgui的调用放到子线程中,就能避免阻塞Kivy主线程。
具体实现步骤
- 导入Python的
threading模块,用于创建子线程 - 将原
callback函数中的数据处理和show(df)逻辑封装成独立函数 - 在
callback中启动子线程执行封装后的函数,而非直接在主线程运行
修改后的完整代码
import kivy import threading from pandasgui import show kivy.require("1.9.1") from kivy.app import App from kivy.uix.button import Button class ButtonApp(App): def build(self): btn = Button(text="Push Me !", font_size="20sp", background_color=(1, 1, 1, 1), color=(0, 0, 0, 1), # 调整文字颜色,避免白色背景下文字不可见 size=(32, 32), size_hint=(.2, .2), pos=(300, 250)) btn.bind(on_press=self.callback) return btn def callback(self, event): # 启动子线程执行数据处理与GUI展示逻辑 threading.Thread(target=self.process_data_and_show_gui, daemon=True).start() def process_data_and_show_gui(self): import pandas as pd import pickle from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay from matplotlib import pyplot as plt data_test = pd.read_csv('test_data.csv') y_test = data_test['target'] X_test = data_test.iloc[:, 1:-1] loaded_model = pickle.load(open(r'GVHD.sav', 'rb')) y_pred = loaded_model.predict(X_test) new_data = pd.concat([X_test, y_test, pd.DataFrame(y_pred, columns=['Predicted response'])], axis=1) new_data.to_csv(r'GVHD_Output_data.csv', index=False) disp = ConfusionMatrixDisplay(confusion_matrix=confusion_matrix(y_test, y_pred, labels=[0, 1], normalize='true'), display_labels=['low risk', 'high risk']) disp = disp.plot(cmap=plt.cm.Blues) disp.figure_.savefig('confusion_matrix_GVHD.jpg') df = pd.read_csv('GVHD_Output_data.csv') show(df) root = ButtonApp() root.run()
关键说明
daemon=True设置子线程为守护线程,会随主线程结束自动退出,避免残留后台线程- 所有耗时逻辑(数据处理、模型预测、pandasgui调用)都放在子线程,Kivy主线程可正常处理界面交互,不会被阻塞
- 如果后续需要在子线程中更新Kivy界面元素,必须用
kivy.clock.Clock.schedule_once将UI操作调度回主线程执行,因为Kivy的UI操作并非线程安全
内容的提问来源于stack exchange,提问作者Anas
相关产品推荐
相关产品推荐

