How does Matplotlib set up the event loop for backend libraries such as Qt while still allowing interaction via the python REPL? At least for Qt the main event loop must run in the main thread, but that's where the REPL is, right, so I'm struggling to see how the two can coexist.
My current attempt starts a QApplication in a separate Python
threading.Thread
def mainloop():
app = QtWidgets.QApplication([])
while True:
app.processEvents()
time.sleep(0.01)
t = threading.Thread(target=mainloop)
t.daemon = True
t.start()
which sort-of works, but I get this warning and it sometimes crashes:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QApplication(0x7fc5cc001820), parent's thread is QThread(0x7fc5cc001a40), current thread is QThread(0x2702160)
Update 1
Here's an attempt using QThread
:
from PyQt5 import QtGui, QtCore, QtWidgets
import time
class Mainloop(QtCore.QObject):
def __init__(self):
super().__init__()
self.app = QtWidgets.QApplication([])
def run(self):
while True:
self.app.processEvents()
time.sleep(1)
t = QtCore.QThread()
m = Mainloop()
m.moveToThread(t)
t.started.connect(m.run)
t.start()
# Essentially I want to be able to interactively build a GUI here
dialog = QtWidgets.QDialog()
dialog.show()
Update 2
Basically, I want to emulate the following interactive python session, that is, not running it as a script to present a ready made GUI. What is the magic that keeps the appearance of the figure window from blocking the python interpreter?
Python 2.7.13 (default, Jan 19 2017, 14:48:08)
Type "copyright", "credits" or "license" for more information.
IPython 5.2.2 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
In [1]: import matplotlib.pyplot as plt
In [2]: plt.ion()
In [3]: fig = plt.figure()
In [4]: # The last command opens a figure window which remains responsive.
...: I can resize it and the window redraws, yet I can still interact
...: with the python interpreter and interactively add new content to t
...: he figure
In [5]: ax = fig.add_subplot(111)
In [6]: # The last command updated the figure window and I can still inter
...: act with the interpreter
In [7]: