1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
#!/usr/bin/env python3
import sys, time
import os
import subprocess
from PyQt5.QtCore import QEvent, pyqtProperty
from PyQt5.QtGui import QWindow, QResizeEvent, QMoveEvent
from PyQt5.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 = pyqtProperty(str, get_command, set_command, reset_command)
if __name__ == '__main__':
from PyQt5.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_())
|