forked from M-Labs/artiq
gui/applets: startup and embedding working
This commit is contained in:
parent
e106ee3f90
commit
597c2e4b17
|
@ -112,6 +112,7 @@ def main():
|
||||||
smgr.register(d_datasets)
|
smgr.register(d_datasets)
|
||||||
|
|
||||||
appletmgr = applets.AppletManager(dock_area)
|
appletmgr = applets.AppletManager(dock_area)
|
||||||
|
atexit_register_coroutine(appletmgr.stop)
|
||||||
smgr.register(appletmgr)
|
smgr.register(appletmgr)
|
||||||
|
|
||||||
if os.name != "nt":
|
if os.name != "nt":
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
|
import asyncio
|
||||||
|
import shlex
|
||||||
|
|
||||||
from quamash import QtCore, QtGui, QtWidgets
|
from quamash import QtCore, QtGui, QtWidgets
|
||||||
from pyqtgraph import dockarea
|
from pyqtgraph import dockarea
|
||||||
|
@ -8,23 +10,50 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class AppletDock(dockarea.Dock):
|
class AppletDock(dockarea.Dock):
|
||||||
def __init__(self, token, name):
|
def __init__(self, token, name, command):
|
||||||
dockarea.Dock.__init__(self, "applet" + str(token),
|
dockarea.Dock.__init__(self, "applet" + str(token),
|
||||||
label="Applet: " + name,
|
label="Applet: " + name,
|
||||||
closable=True)
|
closable=True)
|
||||||
self.setMinimumSize(QtCore.QSize(500, 400))
|
self.setMinimumSize(QtCore.QSize(500, 400))
|
||||||
|
self.token = token
|
||||||
|
self.applet_name = name
|
||||||
|
self.command = command
|
||||||
|
|
||||||
|
async def start(self):
|
||||||
|
command = self.command.format(embed_token=self.token)
|
||||||
|
logger.debug("starting command %s for %s", command, self.applet_name)
|
||||||
|
try:
|
||||||
|
self.process = await asyncio.create_subprocess_exec(
|
||||||
|
*shlex.split(command))
|
||||||
|
except FileNotFoundError:
|
||||||
|
logger.warning("Applet %s failed to start", self.applet_name)
|
||||||
|
else:
|
||||||
|
logger.warning("Applet %s exited", self.applet_name)
|
||||||
|
|
||||||
def capture(self, win_id):
|
def capture(self, win_id):
|
||||||
|
logger.debug("capturing window 0x%x for %s", win_id, self.applet_name)
|
||||||
self.captured_window = QtGui.QWindow.fromWinId(win_id)
|
self.captured_window = QtGui.QWindow.fromWinId(win_id)
|
||||||
self.captured_widget = QtWidgets.QWidget.createWindowContainer(captured_window)
|
self.captured_widget = QtWidgets.QWidget.createWindowContainer(
|
||||||
self.addWidget(captured_widget)
|
self.captured_window)
|
||||||
|
self.addWidget(self.captured_widget)
|
||||||
|
|
||||||
def terminate(self):
|
async def terminate(self):
|
||||||
if hasattr(self, "captured_window"):
|
if hasattr(self, "captured_window"):
|
||||||
self.captured_window.close()
|
self.captured_window.close()
|
||||||
self.captured_widget.deleteLater()
|
self.captured_widget.deleteLater()
|
||||||
del self.captured_window
|
del self.captured_window
|
||||||
del self.captured_widget
|
del self.captured_widget
|
||||||
|
if hasattr(self, "process"):
|
||||||
|
try:
|
||||||
|
await asyncio.wait_for(self.process.wait(), 2.0)
|
||||||
|
except:
|
||||||
|
logger.warning("Applet %s failed to exit, killing",
|
||||||
|
self.applet_name)
|
||||||
|
try:
|
||||||
|
self.process.kill()
|
||||||
|
except ProcessLookupError:
|
||||||
|
pass
|
||||||
|
await self.process.wait()
|
||||||
|
|
||||||
|
|
||||||
class AppletsDock(dockarea.Dock):
|
class AppletsDock(dockarea.Dock):
|
||||||
|
@ -116,18 +145,24 @@ class AppletManager:
|
||||||
logger.warning("Ignored incorrect embed token %d for winid 0x%x",
|
logger.warning("Ignored incorrect embed token %d for winid 0x%x",
|
||||||
token, win_id)
|
token, win_id)
|
||||||
return
|
return
|
||||||
|
self.applet_docks[token].capture(win_id)
|
||||||
|
|
||||||
def create(self, name, command):
|
def create(self, name, command):
|
||||||
token = next(iter(set(range(len(self.applet_docks) + 1))
|
token = next(iter(set(range(len(self.applet_docks) + 1))
|
||||||
- self.applet_docks.keys()))
|
- self.applet_docks.keys()))
|
||||||
dock = AppletDock(token, name)
|
dock = AppletDock(token, name, command)
|
||||||
self.applet_docks[token] = dock
|
self.applet_docks[token] = dock
|
||||||
self.dock_area.floatDock(dock)
|
self.dock_area.floatDock(dock)
|
||||||
|
asyncio.ensure_future(dock.start())
|
||||||
return token
|
return token
|
||||||
|
|
||||||
def delete(self, token):
|
def delete(self, token):
|
||||||
del self.applet_docks[token]
|
del self.applet_docks[token]
|
||||||
|
|
||||||
|
async def stop(self):
|
||||||
|
for dock in self.applet_docks.values():
|
||||||
|
await dock.terminate()
|
||||||
|
|
||||||
def save_state(self):
|
def save_state(self):
|
||||||
return dict()
|
return dict()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue