[vtkusers] wxVTKRenderWindowInteractor use question
Dean Inglis
dean.inglis at camris.ca
Wed Apr 27 09:41:46 EDT 2011
I found the problem solution described here:
http://www.vtk.org/pipermail/vtkusers/2007-April/090723.html
I was using a vtkAxesActor and vtkOrientationMarkerWidget
without a 'self'. Here's a short working script that shows two windows
(I want to be able to layout multiple frames with wxVTKRWI in a wxPython
app)
Dean
#!/usr/bin/env python
import wx
import vtk
from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
class MyFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title,
size=wx.Size(400,400))
self.widget = wxVTKRenderWindowInteractor(self, -1)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.widget, 1, wx.EXPAND)
self.SetSizer(self.sizer)
self.Layout()
self.widget.Enable(1)
self.widget.AddObserver("ExitEvent", lambda o,e,f=self: f.Close())
ren = vtk.vtkRenderer()
self.widget.GetRenderWindow().AddRenderer(ren)
cone = vtk.vtkConeSource()
cone.SetResolution(8)
coneMapper = vtk.vtkPolyDataMapper()
coneMapper.SetInput(cone.GetOutput())
coneActor = vtk.vtkActor()
coneActor.SetMapper(coneMapper)
ren.AddActor(coneActor)
axes = vtk.vtkAxesActor()
self.marker = vtk.vtkOrientationMarkerWidget()
self.marker.SetInteractor( self.widget._Iren )
self.marker.SetOrientationMarker( axes )
self.marker.SetViewport(0.75,0,1,0.25)
self.marker.SetEnabled(1)
ren.ResetCamera()
ren.ResetCameraClippingRange()
cam = ren.GetActiveCamera()
cam.Elevation(10)
cam.Azimuth(70)
# every wx app needs an app
class App(wx.App):
def OnInit(self):
self.frame1 = MyFrame(None,'test1')
self.frame1.Show()
self.frame2 = MyFrame(None,'test2')
self.frame2.Show()
return True
if __name__ == '__main__':
app = App(0)
app.MainLoop()
> not sure if Im phrasing this correctly but I am
> trying to subclass a wx.Frame and during its initialization,
> set up a wxVTKRenderWindowInteractor. In the
> example code that appends the file
> VTK/Wrapping/Python/vtk/wx/wxVTKRenderWindowInteractor.py
> an application instance must first be created:
> <snip>
> import wx
> import vtk
> from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
>
> #--------------------------------------------------------------------
> def simpleExample():
> """Like it says, just a simple example
> """
> # every wx app needs an app
> app = wx.PySimpleApp()
>
> # create the top-level frame, sizer and wxVTKRWI
> frame = wx.Frame(None, -1, "wxVTKRenderWindowInteractor",
> size=(400,400))
> widget = wxVTKRenderWindowInteractor(frame, -1)
> sizer = wx.BoxSizer(wx.VERTICAL)
> sizer.Add(widget, 1, wx.EXPAND)
> frame.SetSizer(sizer)
> frame.Layout()
>
> # It would be more correct (API-wise) to call widget.Initialize() and
> # widget.Start() here, but Initialize() calls RenderWindow.Render().
> # That Render() call will get through before we can setup the
> # RenderWindow() to render via the wxWidgets-created context; this
> # causes flashing on some platforms and downright breaks things on
> # other platforms. Instead, we call widget.Enable(). This means
> # that the RWI::Initialized ivar is not set, but in THIS SPECIFIC CASE,
> # that doesn't matter.
> widget.Enable(1)
>
> widget.AddObserver("ExitEvent", lambda o,e,f=frame: f.Close())
>
> ren = vtk.vtkRenderer()
> widget.GetRenderWindow().AddRenderer(ren)
>
> # later on in the code the app main loop is activated
> <snip>
>
> but I would like to do something like the following:
>
>
> <snip>
> import wx
> import vtk
> from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
>
> class MyFrame(wx.Frame):
>
> def __init__(self, parent, title):
> wx.Frame.__init__(self, parent, -1, title,
> size=wx.Size(400,400))
>
> # create the top-level frame, sizer and wxVTKRWI
> widget = wxVTKRenderWindowInteractor(self, -1) sizer =
> wx.BoxSizer(wx.VERTICAL)
> sizer.Add(widget, 1, wx.EXPAND)
> self.SetSizer(sizer)
> self.Layout()
>
> # It would be more correct (API-wise) to call widget.Initialize() and
> # widget.Start() here, but Initialize() calls RenderWindow.Render().
> # That Render() call will get through before we can setup the
> # RenderWindow() to render via the wxWidgets-created context; this
> # causes flashing on some platforms and downright breaks things on
> # other platforms. Instead, we call widget.Enable(). This means
> # that the RWI::Initialized ivar is not set, but in THIS SPECIFIC CASE,
> # that doesn't matter.
> widget.Enable(1)
>
> widget.AddObserver("ExitEvent", lambda o,e,f=self: f.Close())
>
> ren = vtk.vtkRenderer()
> widget.GetRenderWindow().AddRenderer(ren)
> <snip>
>
> and subclass the application so that in its OnInit method
> instantiates the subclassed frame with the vtkRWI:
>
>
> class App(wx.App):
>
> def OnInit(self):
> self.frame = MyFrame(None,'test')
> self.frame.Show()
> return True
>
> if __name__ == '__main__':
> app = App(0)
> app.MainLoop()
>
>
> however, if I run the example with the latter code, as soon as the
> mouse is over the render window, the app crashes. Why in the first case
> does an application have to be created first (according to the
> documentation in
> vtkRWI it does), while in the second case it appears that this is not
> possible
> using a subclassed wx.App?
>
> Dean
More information about the vtkusers
mailing list