Import LinuxCNC source tree
This commit is contained in:
143
lib/python/qtvcp/widgets/xembed.py
Normal file
143
lib/python/qtvcp/widgets/xembed.py
Normal file
@@ -0,0 +1,143 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys, time
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from qtpy.QtCore import QEvent, Property
|
||||
from qtpy.QtGui import QWindow, QResizeEvent, QMoveEvent
|
||||
from qtpy.QtWidgets import QWidget
|
||||
|
||||
from qtvcp.widgets.widget_baseclass import _HalWidgetBase
|
||||
try:
|
||||
from qtvcp.lib import xembed
|
||||
except:
|
||||
pass
|
||||
from qtvcp import logger
|
||||
|
||||
# Instantiate the libraries with global reference
|
||||
# LOG is for running code logging
|
||||
LOG = logger.getLogger(__name__)
|
||||
|
||||
# Force the log level for this module
|
||||
# LOG.setLevel(logger.INFO) # One of DEBUG, INFO, WARNING, ERROR, CRITICAL
|
||||
|
||||
class XEmbeddable(QWidget, _HalWidgetBase):
|
||||
def __init__(self, parent=None):
|
||||
super(XEmbeddable, self).__init__(parent)
|
||||
|
||||
def _hal_init(self):
|
||||
pass
|
||||
|
||||
def embed(self, command):
|
||||
if '-x {XID}' in command:
|
||||
# convert gladevcp to other type of embedding
|
||||
command = command.replace('-x {XID}', ' --xid ')
|
||||
self.embed_program(command)
|
||||
elif '{XID}' in command:
|
||||
self.let_program_embed(command)
|
||||
else:
|
||||
self.embed_program(command)
|
||||
|
||||
# foreign program embeds it's self in our window
|
||||
def let_program_embed(self,command):
|
||||
self.w = QWindow()
|
||||
self.container = QWidget.createWindowContainer(self.w, self)
|
||||
|
||||
xid = int(self.w.winId())
|
||||
cmd = command.replace('{XID}', str(xid))
|
||||
self.launch(cmd)
|
||||
self.show()
|
||||
# there seems to be a race - sometimes the foreign window doesn't embed
|
||||
time.sleep(.2)
|
||||
|
||||
# we embed foreign program into our window
|
||||
def embed_program(self, command):
|
||||
try:
|
||||
self.external_id = self.launch_xid(command)
|
||||
window = QWindow.fromWinId(self.external_id)
|
||||
self.container = QWidget.createWindowContainer(window, self)
|
||||
self.show()
|
||||
# there seems to be a race - sometimes the foreign window doesn't embed
|
||||
time.sleep(.2)
|
||||
return True
|
||||
except Exception as e:
|
||||
LOG.warning('Exception:{}'.format(command))
|
||||
LOG.warning('Exception:{}'.format( e))
|
||||
raise Exception(e)
|
||||
return False
|
||||
|
||||
def event(self, event):
|
||||
if event.type() == QEvent.Resize:
|
||||
w = QResizeEvent.size(event)
|
||||
try:
|
||||
self.container.resize(w.width(), w.height())
|
||||
except:
|
||||
pass
|
||||
elif event.type() == QEvent.Move:
|
||||
try:
|
||||
self.container.move(QMoveEvent.pos(event))
|
||||
except:
|
||||
pass
|
||||
return True
|
||||
|
||||
# launches program that embeds it's self into our window
|
||||
# The foreign program never resizes as the window changes
|
||||
def launch(self, cmd):
|
||||
c = cmd.split()
|
||||
self.ob = subprocess.Popen(c,stdin = subprocess.PIPE,
|
||||
stdout = subprocess.PIPE)
|
||||
|
||||
# returns program's XID number so we can embed it into our window
|
||||
# This works the best - the window resizes properly
|
||||
# still not great qt4 worked so much better
|
||||
def launch_xid(self,cmd):
|
||||
c = cmd.split()
|
||||
self.ob = subprocess.Popen(c,stdin = subprocess.PIPE,
|
||||
stdout = subprocess.PIPE)
|
||||
sid = self.ob.stdout.readline()
|
||||
LOG.debug( 'XID: {}'.format(sid))
|
||||
return int(sid)
|
||||
|
||||
def _hal_cleanup(self):
|
||||
try:
|
||||
self.ob.terminate()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
class XEmbed(XEmbeddable, _HalWidgetBase):
|
||||
def __init__(self, parent=None):
|
||||
super(XEmbed, self).__init__(parent)
|
||||
self.command = None
|
||||
|
||||
def _hal_init(self):
|
||||
# send embedded program our X window id so it can forward events to us.
|
||||
wid = int(self.QTVCP_INSTANCE_.winId())
|
||||
print('parent wind id', wid)
|
||||
os.environ['QTVCP_FORWARD_EVENTS_TO'] = str(wid)
|
||||
LOG.debug( 'Emed command: {}'.format(self.command))
|
||||
result = self.embed(self.command)
|
||||
if result:
|
||||
return
|
||||
self.x11mess = xembed.X11ClientMessage(self.external_id)
|
||||
|
||||
|
||||
def send_x11_message(self,):
|
||||
self.x11mess.send_client_message()
|
||||
|
||||
def set_command(self, data):
|
||||
self.command = data
|
||||
def get_command(self):
|
||||
return self.command
|
||||
def reset_command(self):
|
||||
self.command = None
|
||||
|
||||
command_string = Property(str, get_command, set_command, reset_command)
|
||||
|
||||
if __name__ == '__main__':
|
||||
from qtpy.QtWidgets import QApplication
|
||||
app = QApplication(sys.argv)
|
||||
ex = XEmbed()
|
||||
ex.embed('halcmd loadusr gladevcp --xid ../../gladevcp/offsetpage.glade')
|
||||
ex.show()
|
||||
ex.setWindowTitle('embed')
|
||||
sys.exit(app.exec())
|
||||
Reference in New Issue
Block a user