title: GTK window capture: VPython (OpenGL) application
body: <p>Having read the documentation for <a href="http://www.vpython.org/contents/FAQ.html" rel="nofollow">VPython</a> and <a href="http://faq.pygtk.org/index.py?req=show&amp;file=faq20.006.htp" rel="nofollow">GTK threading</a>, it seems to me that it would be possible to embed VPython graphics within a gtk GUI.  I know that it is possible with <a href="http://mientki.ruhosting.nl/data_www/pylab_works/pw_vpython_docking.html" rel="nofollow">wx on Windows</a> but I am on Linux and using PyGTK. Now, I have managed to get part of the way.  I can embed a VPython window <strong>provided that it is spawned a separate process</strong>.  What I would like is to embed it as a thread.  The latter would make GUI events that control the OpenGL easier to implement -- via a thread instead of a socket and network calls. </p>
  
  <p><em>Edit: Apparently nobody knows anything about this... Meh.</em></p>
  
  <p>Here is the code I have.  Uncomment the two commented out lines and comment a few obvious others and you can get to the process spawning code. </p>
  
  <pre><code>#!/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):
          gtk.threads_enter()
          self.scene = display.get_selected() 
          self.scene.title = 'OpenGL test'
          s = sphere()
          gtk.threads_leave()
          #P = subprocess.Popen(['python', 'opengl.py'])
          time.sleep(2)
          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],
          #P = subprocess.Popen(['xwininfo', '-name', 'Visual WeldHead'],
                  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()
  </code></pre>