You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I can't figure out how to stop the cocoa mainloop once it's going with the macosx backend. This could be a missing API, or just one that I don't know about.
I suspect an API that exposes sending [NSApp stop] is all that's needed, but I'm not sure.
Code for reproduction
importmatplotlibmatplotlib.use('macosx')
importmatplotlib.pyplotaspltfrommatplotlib.backends.backend_macosximportTimerMac, showdefstop_mainloop():
print("I don't know how to quit you")
t.stop()
t=TimerMac(2000)
t.add_callback(stop_mainloop)
t.start()
show.mainloop()
Actual outcome
Loop runs forever because I don't know how to stop it.
Traceback (most recent call last):
File "testLoop.py", line 14, in <module>
show.mainloop()
AttributeError: 'function' object has no attribute 'mainloop'
(matplotlibdev)
#8773 (@anntzer) changed this behaviour so that show no longer has a mainloop. I'm not sure if this was an oversight or on purpose. I don't understand how events work in the backends well enough to guess about how to get the event loop rolling in master.
Show().mainloop() should still work (the Show class has no instance attributes and effectively serves as a namespace). This should also work with old versions of matplotlib.
I could restore a mainloop attribute on show itself if needed; I just didn't realize that there would be demand for it (but frankly in that case I'd rather just make mainloop a public function, instead of keeping it half-hidden-as-an-attribute-but-public).
In the case of the given example, you can also use show() which does exactly the same thing (it first shows the pyplot windows, but there's none of them in the example).
OK, with Show().mainloop() the callback works, and the GUI window comes up in the toolbar. It can be quit by right-clicking the icon and selecting quit. The terminal window is non responsive to ^C. No idea if thats all desirable or not, but at least there is a graceful way to kill the loop.
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
Activity
tacaswell commentedon Dec 14, 2017
can you try with 2.1? There was some recent work on this.
jklymak commentedon Dec 14, 2017
Yeah on master this gives:
jklymak commentedon Dec 14, 2017
#8773 (@anntzer) changed this behaviour so that
showno longer has amainloop. I'm not sure if this was an oversight or on purpose. I don't understand how events work in the backends well enough to guess about how to get the event loop rolling in master.anntzer commentedon Dec 14, 2017
Show().mainloop()should still work (theShowclass has no instance attributes and effectively serves as a namespace). This should also work with old versions of matplotlib.I could restore a
mainloopattribute onshowitself if needed; I just didn't realize that there would be demand for it (but frankly in that case I'd rather just make mainloop a public function, instead of keeping it half-hidden-as-an-attribute-but-public).In the case of the given example, you can also use
show()which does exactly the same thing (it first shows the pyplot windows, but there's none of them in the example).jklymak commentedon Dec 14, 2017
OK, with
Show().mainloop()the callback works, and the GUI window comes up in the toolbar. It can be quit by right-clicking the icon and selecting quit. The terminal window is non responsive to ^C. No idea if thats all desirable or not, but at least there is a graceful way to kill the loop.minrk commentedon Dec 15, 2017
There's still not a programmatic way to do it, right? That's what I need right now.
I figured it out with ctypes, cribbing heavily from some forgotten work in IPython.
I need a way to call
[NSApp stop]followed by sending a wake event to trigger the teardown. Here's a script that shows everything working:minrk commentedon Dec 15, 2017
If there were a
stop_mainloopfunction somewhere, it should be a pretty simple two calls:[NSApp stop]and sending the wake event.github-actions commentedon Apr 28, 2023
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
oscargus commentedon May 28, 2023
Reopening this since there is a PR proposed that solves it.