123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- """
- Description:
- Provides a pyGtk vtkRenderWindowInteractor widget. This embeds a
- vtkRenderWindow inside a GTK widget and uses the
- vtkGenericRenderWindowInteractor for the event handling. This is
- similar to GtkVTKRenderWindowInteractor.py.
- The extensions here allow the use of gtkglext rather than gtkgl and
- pygtk-2 rather than pygtk-0. It requires pygtk-2.0.0 or later.
- There is a working example at the bottom.
- Credits:
- John Hunter <jdhunter@ace.bsd.uchicago.edu> developed and tested
- this code based on VTK's GtkVTKRenderWindow.py and extended it to
- work with pygtk-2.0.0.
- License:
- VTK license.
- """
- import sys
- import pygtk
- pygtk.require('2.0')
- import gtk
- from gtk import gdk
- import gtk.gtkgl
- from vtkmodules.vtkRenderingCore import vtkRenderWindow
- from vtkmodules.vtkRenderingUI import vtkGenericRenderWindowInteractor
- class GtkGLExtVTKRenderWindowInteractor(gtk.gtkgl.DrawingArea):
- """ Embeds a vtkRenderWindow into a pyGTK widget and uses
- vtkGenericRenderWindowInteractor for the event handling. This
- class embeds the RenderWindow correctly. A __getattr__ hook is
- provided that makes the class behave like a
- vtkGenericRenderWindowInteractor."""
- def __init__(self, *args):
- gtk.gtkgl.DrawingArea.__init__(self)
- self.set_double_buffered(gtk.FALSE)
- self._RenderWindow = vtkRenderWindow()
- # private attributes
- self.__Created = 0
- self._ActiveButton = 0
- self._Iren = vtkGenericRenderWindowInteractor()
- self._Iren.SetRenderWindow(self._RenderWindow)
- self._Iren.GetInteractorStyle().SetCurrentStyleToTrackballCamera()
- self._Iren.AddObserver('CreateTimerEvent', self.CreateTimer)
- self._Iren.AddObserver('DestroyTimerEvent', self.DestroyTimer)
- self.ConnectSignals()
- # need this to be able to handle key_press events.
- self.set_flags(gtk.CAN_FOCUS)
- def set_size_request(self, w, h):
- gtk.gtkgl.DrawingArea.set_size_request(self, w, h)
- self._RenderWindow.SetSize(w, h)
- self._Iren.SetSize(w, h)
- self._Iren.ConfigureEvent()
- def ConnectSignals(self):
- self.connect("realize", self.OnRealize)
- self.connect("expose_event", self.OnExpose)
- self.connect("configure_event", self.OnConfigure)
- self.connect("button_press_event", self.OnButtonDown)
- self.connect("button_release_event", self.OnButtonUp)
- self.connect("motion_notify_event", self.OnMouseMove)
- self.connect("enter_notify_event", self.OnEnter)
- self.connect("leave_notify_event", self.OnLeave)
- self.connect("key_press_event", self.OnKeyPress)
- self.connect("delete_event", self.OnDestroy)
- self.add_events(gdk.EXPOSURE_MASK| gdk.BUTTON_PRESS_MASK |
- gdk.BUTTON_RELEASE_MASK |
- gdk.KEY_PRESS_MASK |
- gdk.POINTER_MOTION_MASK |
- gdk.POINTER_MOTION_HINT_MASK |
- gdk.ENTER_NOTIFY_MASK | gdk.LEAVE_NOTIFY_MASK)
- def __getattr__(self, attr):
- """Makes the object behave like a
- vtkGenericRenderWindowInteractor"""
- if attr == '__vtk__':
- return lambda t=self._Iren: t
- elif hasattr(self._Iren, attr):
- return getattr(self._Iren, attr)
- else:
- raise AttributeError(self.__class__.__name__ +
- " has no attribute named " + attr)
- def CreateTimer(self, obj, event):
- gtk.timeout_add(10, self._Iren.TimerEvent)
- def DestroyTimer(self, obj, event):
- """The timer is a one shot timer so will expire automatically."""
- return 1
- def GetRenderWindow(self):
- return self._RenderWindow
- def Render(self):
- if self.__Created:
- self._RenderWindow.Render()
- def OnRealize(self, *args):
- if self.__Created == 0:
- # you can't get the xid without the window being realized.
- self.realize()
- if sys.platform=='win32':
- win_id = str(self.widget.window.handle)
- else:
- win_id = str(self.widget.window.xid)
- self._RenderWindow.SetWindowInfo(win_id)
- #self._Iren.Initialize()
- self.__Created = 1
- return gtk.TRUE
- def OnConfigure(self, widget, event):
- self.widget=widget
- self._Iren.SetSize(event.width, event.height)
- self._Iren.ConfigureEvent()
- self.Render()
- return gtk.TRUE
- def OnExpose(self, *args):
- self.Render()
- return gtk.TRUE
- def OnDestroy(self, event=None):
- self.hide()
- del self._RenderWindow
- self.destroy()
- return gtk.TRUE
- def _GetCtrlShift(self, event):
- ctrl, shift = 0, 0
- if ((event.state & gdk.CONTROL_MASK) == gdk.CONTROL_MASK):
- ctrl = 1
- if ((event.state & gdk.SHIFT_MASK) == gdk.SHIFT_MASK):
- shift = 1
- return ctrl, shift
- def OnButtonDown(self, wid, event):
- """Mouse button pressed."""
- m = self.get_pointer()
- ctrl, shift = self._GetCtrlShift(event)
- self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
- chr(0), 0, None)
- button = event.button
- if button == 3:
- self._Iren.RightButtonPressEvent()
- return gtk.TRUE
- elif button == 1:
- self._Iren.LeftButtonPressEvent()
- return gtk.TRUE
- elif button == 2:
- self._Iren.MiddleButtonPressEvent()
- return gtk.TRUE
- else:
- return gtk.FALSE
- def OnButtonUp(self, wid, event):
- """Mouse button released."""
- m = self.get_pointer()
- ctrl, shift = self._GetCtrlShift(event)
- self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
- chr(0), 0, None)
- button = event.button
- if button == 3:
- self._Iren.RightButtonReleaseEvent()
- return gtk.TRUE
- elif button == 1:
- self._Iren.LeftButtonReleaseEvent()
- return gtk.TRUE
- elif button == 2:
- self._Iren.MiddleButtonReleaseEvent()
- return gtk.TRUE
- return gtk.FALSE
- def OnMouseMove(self, wid, event):
- """Mouse has moved."""
- m = self.get_pointer()
- ctrl, shift = self._GetCtrlShift(event)
- self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
- chr(0), 0, None)
- self._Iren.MouseMoveEvent()
- return gtk.TRUE
- def OnEnter(self, wid, event):
- """Entering the vtkRenderWindow."""
- self.grab_focus()
- m = self.get_pointer()
- ctrl, shift = self._GetCtrlShift(event)
- self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
- chr(0), 0, None)
- self._Iren.EnterEvent()
- return gtk.TRUE
- def OnLeave(self, wid, event):
- """Leaving the vtkRenderWindow."""
- m = self.get_pointer()
- ctrl, shift = self._GetCtrlShift(event)
- self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
- chr(0), 0, None)
- self._Iren.LeaveEvent()
- return gtk.TRUE
- def OnKeyPress(self, wid, event):
- """Key pressed."""
- m = self.get_pointer()
- ctrl, shift = self._GetCtrlShift(event)
- keycode, keysym = event.keyval, event.string
- key = chr(0)
- if keycode < 256:
- key = chr(keycode)
- self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
- key, 0, keysym)
- self._Iren.KeyPressEvent()
- self._Iren.CharEvent()
- return gtk.TRUE
- def OnKeyRelease(self, wid, event):
- "Key released."
- m = self.get_pointer()
- ctrl, shift = self._GetCtrlShift(event)
- keycode, keysym = event.keyval, event.string
- key = chr(0)
- if keycode < 256:
- key = chr(keycode)
- self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
- key, 0, keysym)
- self._Iren.KeyReleaseEvent()
- return gtk.TRUE
- def Initialize(self):
- if self.__Created:
- self._Iren.Initialize()
- def SetPicker(self, picker):
- self._Iren.SetPicker(picker)
- def GetPicker(self, picker):
- return self._Iren.GetPicker()
- def main():
- from vtkmodules.vtkFiltersSources import vtkConeSource
- from vtkmodules.vtkRenderingCore import vtkActor, vtkPolyDataMapper, vtkRenderer
- # load implementations for rendering and interaction factory classes
- import vtkmodules.vtkRenderingOpenGL2
- import vtkmodules.vtkInteractionStyle
- # The main window
- window = gtk.Window(gtk.WINDOW_TOPLEVEL)
- window.set_title("A GtkVTKRenderWindow Demo!")
- window.connect("destroy", gtk.mainquit)
- window.connect("delete_event", gtk.mainquit)
- window.set_border_width(10)
- # A VBox into which widgets are packed.
- vbox = gtk.VBox(spacing=3)
- window.add(vbox)
- vbox.show()
- # The GtkVTKRenderWindow
- gvtk = GtkGLExtVTKRenderWindowInteractor()
- #gvtk.SetDesiredUpdateRate(1000)
- gvtk.set_size_request(400, 400)
- vbox.pack_start(gvtk)
- gvtk.show()
- gvtk.Initialize()
- gvtk.Start()
- # prevents 'q' from exiting the app.
- gvtk.AddObserver("ExitEvent", lambda o,e,x=None: x)
- # The VTK stuff.
- cone = vtkConeSource()
- cone.SetResolution(80)
- coneMapper = vtkPolyDataMapper()
- coneMapper.SetInputConnection(cone.GetOutputPort())
- #coneActor = vtkLODActor()
- coneActor = vtkActor()
- coneActor.SetMapper(coneMapper)
- coneActor.GetProperty().SetColor(0.5, 0.5, 1.0)
- ren = vtkRenderer()
- gvtk.GetRenderWindow().AddRenderer(ren)
- ren.AddActor(coneActor)
- # A simple quit button
- quit = gtk.Button("Quit!")
- quit.connect("clicked", gtk.mainquit)
- vbox.pack_start(quit)
- quit.show()
- # show the main window and start event processing.
- window.show()
- gtk.mainloop()
- if __name__ == "__main__":
- main()
|