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

MNE/Matplotlib可视化导致easygui-qt脚本退出问题咨询

问题:整合MNE、Matplotlib与easygui-qt时脚本提前退出,无法执行后续代码

我在整合MNE、Matplotlib与easygui-qt时遇到故障,无法准确定位根源。需求是:展示MNE生成的交互式图形,同时用easygui-qt弹出模态弹窗,允许用户操作图形后通过弹窗提交输入。但生成图形时Matplotlib会开启交互模式,导致用户完成弹窗输入后脚本直接退出,后续代码无法执行。

示例代码

import matplotlib
import mne
from mne.datasets import sample
from mne.io import read_raw_fif
import easygui_qt.easygui_qt as gui
import matplotlib.pyplot as plt

matplotlib.use('Qt5Agg')
mne.viz.set_browser_backend('qt')   # or "matplotlib"


fname = sample.data_path() / "MEG" / "sample" / "sample_audvis_raw.fif"
raw = read_raw_fif(fname, preload=False, verbose=False)
raw.crop(0, 60).pick("eeg")
raw.load_data(verbose=False)

input1 = gui.get_continue_or_cancel(title="Input 1", message="", continue_button_text="T", cancel_button_text="F")
fig = raw.plot(verbose=False, show=True)    # can set show=False with same downstream effect
# plt.ioff()                        # this has no effect
# matplotlib.interactive(False)     # this has no effect
input2 = gui.get_continue_or_cancel(title="Input 2", message="", continue_button_text="T", cancel_button_text="F")
print(f"In 1: {input1}\t\tIn 2: {input2}")

环境信息

包版本

matplotlib:3.8.4
PyQt5: 5.15.11
easygui-qt: 0.9.3
mne: 1.9.0
mne-qt-browser: 0.6.3

系统信息

>>> mne.sys_info()
Platform             Windows-11-10.0.26100-SP0
Python               3.12.3 (tags/v3.12.3:f6650f9, Apr  9 2024, 14:05:25) [MSC v.1938 64 bit (AMD64)]
Executable           C:\Path\To\venv\Scripts\python.exe
CPU                  13th Gen Intel(R) Core(TM) i7-13700 (24 cores)
Memory               63.7 GiB
Core
 + mne               1.9.0 (latest release)
 + numpy             2.1.1 (OpenBLAS 0.3.27 with 24 threads)
 + scipy             1.15.1
 + matplotlib        3.8.4Backend QtAgg is interactive backend. Turning interactive mode on.
 (backend=QtAgg)
Numerical (optional)
 + sklearn           1.6.1
 + pandas            2.2.3
 + h5py              3.12.1
 - unavailable       numba, nibabel, nilearn, dipy, openmeeg, cupy, h5io
Visualization (optional)
 + qtpy              2.4.3 (PyQt6=6.8.2)
 + pyqtgraph         0.13.7
 + mne-qt-browser    0.6.3
 - unavailable       pyvista, pyvistaqt, vtk, ipympl, ipywidgets, trame_client, trame_server, trame_vtk, trame_vuetify
Ecosystem (optional)
 + mne-icalabel      0.7.0
 - unavailable       mne-bids, mne-nirs, mne-features, mne-connectivity, mne-bids-pipeline, neo, eeglabio, edfio, mffpy, pybv

解决方案

原因分析

MNE的Qt后端浏览器(mne-qt-browser)基于PyQtGraph运行,独立于Matplotlib的事件循环。当调用raw.plot()时,它会临时启动Qt事件循环,但弹窗关闭后事件循环终止,导致脚本直接退出。手动关闭Matplotlib交互模式无效,因为MNE的Qt绘图不依赖Matplotlib的事件系统。

解决方法:手动管理Qt事件循环

通过QApplication统一控制Qt事件循环,确保图形窗口和弹窗都能正常运行,且脚本不会提前退出。修改后的代码如下:

import matplotlib
import mne
from mne.datasets import sample
from mne.io import read_raw_fif
import easygui_qt.easygui_qt as gui
from PyQt5.QtWidgets import QApplication
import sys

matplotlib.use('Qt5Agg')
mne.viz.set_browser_backend('qt')

# 初始化QApplication,避免重复创建实例
app = QApplication.instance() or QApplication(sys.argv)

fname = sample.data_path() / "MEG" / "sample" / "sample_audvis_raw.fif"
raw = read_raw_fif(fname, preload=False, verbose=False)
raw.crop(0, 60).pick("eeg")
raw.load_data(verbose=False)

input1 = gui.get_continue_or_cancel(title="Input 1", message="", continue_button_text="T", cancel_button_text="F")

# 以show=False启动浏览器,避免自动触发事件循环
fig = raw.plot(verbose=False, show=False)
# 手动显示图形窗口
fig.show()

# 弹窗操作,此时事件循环由QApplication管理
input2 = gui.get_continue_or_cancel(title="Input 2", message="", continue_button_text="T", cancel_button_text="F")

print(f"In 1: {input1}\t\tIn 2: {input2}")

# 保持事件循环运行,直到用户关闭所有Qt窗口
sys.exit(app.exec_())

关键说明

  1. 统一事件循环:通过QApplication接管所有Qt组件(MNE浏览器、easygui-qt弹窗)的事件处理,避免多个事件循环冲突。
  2. 手动控制图形显示:用show=False启动MNE浏览器,再手动调用fig.show(),防止MNE自行启动临时事件循环。
  3. 保持脚本运行:最后调用app.exec_()阻塞脚本,直到用户关闭所有Qt窗口,确保后续代码执行完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 11:50:07