Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Can't interrupt start_event_loop() at backend_qt5.py::FigureCanvasQt #13315

Closed as not planned
Labels
GUI: Qtstatus: closed as inactiveIssues closed by the "Stale" Github Action. Please comment on any you think should still be open.status: inactiveMarked by the “Stale” Github Action
@vdrhtc

Description

@vdrhtc

Bug report

Bug summary (suggested fix is in the very bottom)

This internal method is used inplt.pause() and BlockingInput class (I don't know what the latter does).

The problem is approximately since Matplotlib 2.0.0 (but I don't know what exactly has changed). In the current implementation, the method execution can't be interrupted easily since it is based onevent_loop.exec_() (internally C++) function that locks out the Python interpreter and prevents it from processing SIGINT as KeyboardInterrupt.

The problem is clearly visible when you run some kind of animation (see example below), since the SIGINT is getting understood as KeyboardInterrupt by the target function of the Timer (which is in Python and thus the interpreter gets to run from time to time in the event loop). However, this exception in the timer target can't stop the even loop, and it continues.

In overall, this problem actually rendersplt.pause() practically unusable (this, and the window focusing issues). So either we should deprecateplt.pause() or fix it, as I suggest below.

Code for reproduction

%pylabqt5importnumpyasnpimportmatplotlib.pyplotaspltfrommatplotlib.animationimportFuncAnimationfrommatplotlib._pylab_helpersimportGcfstopped=Falsefig,ax=plt.subplots()xdata,ydata= [], []ln,=plt.plot([], [],'ro')definit():ax.set_xlim(0,2*np.pi)ax.set_ylim(-1,1)returnln,defupdate(frame):xdata.append(frame)ydata.append(np.sin(frame))ln.set_data(xdata,ydata)ifframe==2*np.pi:stopped=Truereturnln,ani=FuncAnimation(fig,update,frames=np.linspace(0,2*np.pi,128),init_func=init,blit=True,interval=50,repeat=False)# wait for the plotting/underlying process to endtry:whilenotstopped:manager=Gcf.get_fig_manager(fig.number)manager.canvas.start_event_loop(1)exceptKeyboardInterrupt:plt.close(fig)print("KeyboardInterrupt caught")exceptAttributeError:print("Figure closed from GUI")

Actual outcome

On pressing stop button in Jupyter:

And then the waiting cycle continues with no error. The exceptions on the Qt event loop get caught somewhere inside?

Expected outcome

Clean stop and closed figure on theexcept KeyboardInterrupt clause.

Matplotlib version

Operating system: 4.18.16-100.fc27.x86_64Matplotlib version: 3.0.2Matplotlib backend: Qt5AggPython version: 3.6IPython: 7.2.0Jupyter notebook: 5.7.4

Everything installed with pip in a virtualenv.

Suggested fix

This problem has annoyed me for quite some time, and I am very glad that it seems that there is the solution. It is very closely related to#13302, and is solved similarly (usingsignal.set_wakeup_fd() andsocket.createsocketpair()).

The problematic method should be rewritten as follows:

defstart_event_loop(self,timeout=0):ifhasattr(self,"_event_loop")andself._event_loop.isRunning():raiseRuntimeError("Event loop already running")self._event_loop=event_loop=QtCore.QEventLoop()iftimeout:timer=QtCore.QTimer.singleShot(timeout*1000,event_loop.quit)SIGINTHandler(qApp)interrupted=Falsedefsigint_handler():nonlocalinterruptedevent_loop.quit()interrupted=Trueold_sigint_handler=signal.getsignal(signal.SIGINT)signal.signal(signal.SIGINT,lambdasig,_:sigint_handler())try:event_loop.exec_()finally:signal.signal(signal.SIGINT,old_sigint_handler)ifinterrupted:raiseKeyboardInterrupt

SIGINTHandler class may be found in#13306

Metadata

Metadata

Assignees

No one assigned

    Labels

    GUI: Qtstatus: closed as inactiveIssues closed by the "Stale" Github Action. Please comment on any you think should still be open.status: inactiveMarked by the “Stale” Github Action

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp