From: Yann G. <ygo...@is...> - 2012-06-08 14:58:50
|
Quoth Bruce Sherwood on Fri, Jun 08, 2012 at 07:52:34 -0600 > The Linux version of VPython is based on GTK. Ah, then there maybe some hope. I am running on Linux. What I want to do is to embed a VPython window within a bigger GTK GUI. What I'd thought I'd do was create a gtk.Socket() and use that to embed the VPython window. This works like a charm provided that the VPython window and the GUI window are created by different processes. The problem happens when I try to use threads -- yes, I know "I had a problem. Then I used threading. Now Iav he wto pbleroms." ... Still, I feel I am very close to it working. In the code below, I get: test_opengl.py:62: GtkWarning: gtksocket.c:886: Can't add non-GtkPlug to GtkSocket socket.add_id(long(self.OpenGLWindowID)) /usr/bin/ipython:62: GtkWarning: IA__gdk_error_trap_pop: assertion `gdk_error_traps != NULL' failed as an error. But if the code in GTKWindowThreadClass.run() is copied and pasted into its own script (with the correct value of OpenGLWindowID as given by xwininfo) then it works: the VPython window embeds into the GTK one. Can anyone see what I am doing wrong? Source code follows -- apologies for the spare commenting but it should be simple enough to follow. ================================================================================ #!/usr/bin/env python # -*- coding: utf-8 -*- import time from visual import * import threading import Queue import gtk import pygtk import re import subprocess class OPenGLThreadClass (threading.Thread): """Thread running the VPython code.""" def __init__(self, queue): threading.Thread.__init__(self) self.queue = queue self.name = 'OpenGLThread' def run (self): self.scene = display.get_selected() self.scene.title = 'OpenGL test' s = sphere() self.queue.put(self.find_window_id()) self.queue.task_done() def find_window_id (self): """Gets the OpenGL window ID.""" pattern = re.compile('0x[0-9abcdef]{7}') P = subprocess.Popen(['xwininfo', '-name', self.scene.title], stdout=subprocess.PIPE) for line in P.stdout.readlines(): match = pattern.findall(line) if len(match): ret = long(match[0], 16) print("OpenGL window id is %d (%s)" % (ret, hex(ret))) return ret class GTKWindowThreadClass (threading.Thread): """Thread running the GTK code.""" def __init__ (self, winID): threading.Thread.__init__(self) self.OpenGLWindowID = winID self.name = 'GTKThread' def run (self): """Draw the GTK GUI.""" gtk.threads_enter() window = gtk.Window() window.show() socket = gtk.Socket() socket.show() window.add(socket) window.connect("destroy", lambda w: gtk.main_quit()) print("Got winID as %d (%s)" % (self.OpenGLWindowID, hex(self.OpenGLWindowID))) socket.add_id(long(self.OpenGLWindowID)) gtk.main() gtk.threads_leave() def main (): thread = {} print("Embedding OpenGL/VPython into GTK GUI") queue = Queue.Queue() thread['OpenGL'] = OPenGLThreadClass(queue) thread['OpenGL'].start() winID = queue.get() print("Got winID as %d (%s)" % (winID, hex(winID))) gtk.gdk.threads_init() thread['GTK'] = GTKWindowThreadClass(winID) thread['GTK'].start() if __name__ == "__main__": main() ================================================================================ -- GPG Fingerprint 8666 7F9A 17E7 AC8E CC36 1D1E C707 D658 6685 2528 The views expressed in this e-mail may or may not reflect those of the author and do not necessarily reflect those of Isotek Oil and Gas Ltd. |