def __init__(self, queue=None, rqueue=None): from tugalinhas.turtlescene import TurtleScene, TurtleView super().__init__() self._scene = TurtleScene() self._view = TurtleView(self._scene) self._layout = QtWidgets.QVBoxLayout(self) self._layout.addWidget(self._view) self.setMinimumSize(800, 600) self._namespace = self._scene.getNamespace() self._queue = queue self._rqueue = rqueue self.startTimer(1000 / 30)
class _TurtleWindow(QtWidgets.QWidget): """ A turtle window that should be ran in a background subprocess. We cannot use threads since Qt expects that the GUI runs in the main thread. It communicates with the main process using a Queue of commands. """ _instance = None def __new__(cls, queue=None, rqueue=None): if cls._instance is None: return super().__new__(cls, queue, rqueue) else: return cls._instance def __init__(self, queue=None, rqueue=None): from tugalinhas.turtlescene import TurtleScene, TurtleView super().__init__() self._scene = TurtleScene() self._view = TurtleView(self._scene) self._layout = QtWidgets.QVBoxLayout(self) self._layout.addWidget(self._view) self.setMinimumSize(800, 600) self._namespace = self._scene.getNamespace() self._queue = queue self._rqueue = rqueue self.startTimer(1000 / 30) def timerEvent(self, timer): if not self._queue.empty(): task = self._queue.get() self.consume(task) def keyPressEvent(self, ev): key = ev.key() modifiers = ev.modifiers() def consume(self, task): name, args, kwargs = task if name.startswith('*'): method = getattr(self._namespace, name[1:]) self._rqueue.put(method(*args, **kwargs)) else: method = getattr(self._namespace, name) method(*args, **kwargs)