wx.aui and VTK

Hello,
I have a problem using wxPython wx.aui and VTK. If I create a VTK
panel as main and a second VTK panel as a floating panel when I try to
dock the second panel on the main I get an X error on Lynux. On
Windows everything works well. I already tried to ask information on
the VTK-user mailing list but I get no useful help about.
I met this issue with the following configuration:

Python 2.5
wxPython 2.8.9.0 -> 2.8.10.1
VTK5.0,-> 5.4

This is the error message I get:

(python:12045): Gdk-WARNING **: /build/buildd/gtk+2.0-2.14.4/gdk/x11/
gdkdrawable-x11.c:878 drawable is not a pixmap or window
(python:12045): Gdk-WARNING **: /build/buildd/gtk+2.0-2.14.4/gdk/x11/
gdkdrawable-x11.c:878 drawable is not a pixmap or window
(python:12045): Gdk-WARNING **: /build/buildd/gtk+2.0-2.14.4/gdk/x11/
gdkdrawable-x11.c:878 drawable is not a pixmap or window
(python:12045): Gdk-WARNING **: /build/buildd/gtk+2.0-2.14.4/gdk/x11/
gdkdrawable-x11.c:878 drawable is not a pixmap or window
The program 'python' received an X Window System error.
This probably reflects a bug in the program.
The error was 'BadWindow (invalid Window parameter)'.
  (Details: serial 56244 error_code 3 request_code 12 minor_code 0)
  (Note to programmers: normally, X errors are reported
asynchronously;
   that is, you will receive the error a while after causing it.
   To debug your program, run it with the --sync command line
   option to change this behavior. You can then get a meaningful
   backtrace from your debugger if you break on the gdk_x_error()
function.)
Locking assertion failure. Backtrace:
#0 /usr/lib/libxcb-xlib.so.0 [0x7f58aec789fc]
#1 /usr/lib/libxcb-xlib.so.0(xcb_xlib_lock+0x17) [0x7f58aec78b77]
#2 /usr/lib/libX11.so.6 [0x7f58b02908c0]
#3 /usr/lib/libGL.so.1 [0x7f58b0c60086]

This is an example script that reproduce the error on Lynux:

import vtk
import wx
import wx.aui
from vtk.wx.wxVTKRenderWindowInteractor import *

···

#--------------------------------------------------------------------------------
class VTKCanvas(wx.Panel):
  def __init__(self, parent, id):
    wx.Panel.__init__(self, parent, id, size=(350,350))

    self.parent = parent

    self.widget = wxVTKRenderWindowInteractor(self, -1)
    self.widget.Enable(1)

    self.ren = vtk.vtkRenderer()
    self.widget.GetRenderWindow().AddRenderer(self.ren)

    sizer = wx.BoxSizer(wx.VERTICAL)
    sizer.Add(self.widget, 1, wx.EXPAND)
    self.SetSizer(sizer)
    self.Layout()

    self.widget.Render()

#--------------------------------------------------------------------------------
class Test(wx.Frame):

  def __init__(self, parent, id):

    wx.Frame.__init__(self, parent, id=-1, title="AUI Test", pos=
(0,0),
      size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE |
wx.SUNKEN_BORDER |
      wx.CLIP_CHILDREN|wx.MAXIMIZE)

    self._mgr = wx.aui.AuiManager()
    self._mgr.SetManagedWindow(self)
    self.SetMinSize(wx.Size(400, 300))

    self.vtkPanel =[]
    # Create VTK canvas
    self.startPanel()

    self.Bind(wx.EVT_CLOSE, self.onExit)
    self._mgr.Update()

  def startPanel(self):
    self._mgr.AddPane(self.createVTKCanvas(), wx.aui.AuiPaneInfo
().CenterPane().Name("Main_Window"))
    self._mgr.AddPane(self.createVTKCanvas(), wx.aui.AuiPaneInfo().Left
().
                      Caption("Second_Window").
                      Layer(1).Float().Name("Second_Window"))
    self._mgr.Update()

  def createVTKCanvas(self):
    win = VTKCanvas(self, -1)
    self.vtkPanel.append(win)
    return win

  def onExit(self, event):
    # Destroy each VTK Canvas
    for win in self.vtkPanel:
      win.ren.RemoveAllViewProps()
      del win.ren
      win.widget.GetRenderWindow().Finalize()
      win.widget.SetRenderWindow(None)
      del win.widget
    # Destroy the Frame
    self._mgr.UnInit()
    del self._mgr
    self.Destroy()

#--------------------------------------------------------------------------------
if __name__ == "__main__":
  app = wx.App(0)
  main = Test(None, wx.ID_ANY)
  main.Show()
  main.Maximize()
  app.MainLoop()

Thank you.

Nicola

Nicola Creati wrote:

Hello,
I have a problem using wxPython wx.aui and VTK. If I create a VTK
panel as main and a second VTK panel as a floating panel when I try to
dock the second panel on the main I get an X error on Lynux. On
Windows everything works well. I already tried to ask information on
the VTK-user mailing list but I get no useful help about.
I met this issue with the following configuration:

The program 'python' received an X Window System error.
This probably reflects a bug in the program.
The error was 'BadWindow (invalid Window parameter)'.

This is just a shot in the dark but the way that the VTK integration works is we give VTK the handle of the X-Window to draw upon and it then deals with it at that low level. When an AUI pane is docked the contents window is reparented to become a child of the managed docking window instead of the floating window, and the floating window is destroyed. So my guess is that either VTK is looking up at the parents of the handle that is given to it, (and that parent is destroyed by docking) or the reparenting process is altering the window handle given to VTK in some way that conflicts with VTK.

The only suggestion I have is to try using an extra panel between the AUI pane and the VTK window and see if that will insulate it enough to avoid the problem.

···

--
Robin Dunn
Software Craftsman

Thank for the info. If is something I supposed.
I tried to modify the script to add an intermediate panel but it did
not solve the problem.
I'm attaching the modified code, is it what you meant?

Nicola

# -*- coding: utf-8 -*-

import vtk
import wx
import wx.aui
from vtk.wx.wxVTKRenderWindowInteractor import *

···

#--------------------------------------------------------------------------------
class VTKmain(wx.Panel):
  def __init__(self, parent, id):
    wx.Panel.__init__(self, parent, id)

    self.rwi = wxVTKRenderWindowInteractor(self, wx.NewId())
    self.rwi.Enable(1)

    self.ren = vtk.vtkRenderer()
    self.rwi.GetRenderWindow().AddRenderer(self.ren)

    sizer = wx.BoxSizer(wx.VERTICAL)
    sizer.Add(self.rwi, 1, wx.EXPAND)
    self.SetSizer(sizer)
    self.Layout()
    self.rwi.Render()

#--------------------------------------------------------------------------------
class VTKsecond(wx.Panel):
  def __init__(self, parent, id):
    wx.Panel.__init__(self, parent, id, size=(350, 350))

    self.panel = wx.Panel(self, -1)

    self.rwi = wxVTKRenderWindowInteractor(self.panel, wx.NewId())
    self.rwi.Enable(1)

    self.ren = vtk.vtkRenderer()
    self.rwi.GetRenderWindow().AddRenderer(self.ren)

    sizer = wx.BoxSizer(wx.VERTICAL)
    sizer.Add(self.rwi, 1, wx.EXPAND)
    self.panel.SetSizer(sizer)

    sizer2 = wx.BoxSizer(wx.VERTICAL)
    sizer2.Add(self.panel, 1, wx.EXPAND)
    self.SetSizer(sizer2)
    self.Layout()

#--------------------------------------------------------------------------------
class Test(wx.Frame):

  def __init__(self, parent, id):

    wx.Frame.__init__(self, parent, id=-1, title="AUI Test", pos=
(0,0),
      size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE |
wx.SUNKEN_BORDER |
      wx.CLIP_CHILDREN|wx.MAXIMIZE)

    self._mgr = wx.aui.AuiManager()
    self._mgr.SetManagedWindow(self)
    self.SetMinSize(wx.Size(400, 300))

    self.vtkPanel =
    # Create VTK canvas
    self.startPanel()

    self.Bind(wx.EVT_CLOSE, self.onExit)
    self._mgr.Update()

  def startPanel(self):
    self._mgr.AddPane(self.createVTKmain(), wx.aui.AuiPaneInfo
().CenterPane().Name("Main_Window"))
    self._mgr.AddPane(self.createVTKsecond(), wx.aui.AuiPaneInfo().Left
().
                      Caption("Second_Window").Float().Name
("Second_Window"))
    self._mgr.Update()

  def createVTKmain(self):
    self.mainWin = VTKmain(self, -1)
    return self.mainWin

  def createVTKsecond(self):
    self.secondWin = VTKsecond(self, -1)
    return self.secondWin

  def onExit(self, event):
    # Destroy main VTK Canvas
    self.mainWin.ren.RemoveAllViewProps()
    del self.mainWin.ren
    self.mainWin.rwi.GetRenderWindow().Finalize()
    self.mainWin.rwi.SetRenderWindow(None)
    del self.mainWin.rwi
    # Destroy second VTK Canvas
    self.secondWin.ren.RemoveAllViewProps()
    del self.secondWin.ren
    self.secondWin.rwi.GetRenderWindow().Finalize()
    self.secondWin.rwi.SetRenderWindow(None)
    del self.secondWin.rwi

    self._mgr.UnInit()
    del self._mgr
    self.Destroy()

#--------------------------------------------------------------------------------
if __name__ == "__main__":
  app = wx.App(0)
  main = Test(None, wx.ID_ANY)
  main.Show()
  main.Maximize()
  app.MainLoop()

On Jun 19, 2:40 am, Robin Dunn <ro...@alldunn.com> wrote:

Nicola Creati wrote:
> Hello,
> I have a problem using wxPython wx.aui and VTK. If I create a VTK
> panel as main and a second VTK panel as a floating panel when I try to
> dock the second panel on the main I get an X error on Lynux. On
> Windows everything works well. I already tried to ask information on
> the VTK-user mailing list but I get no useful help about.
> I met this issue with the following configuration:
> The program 'python' received an X Window System error.
> This probably reflects a bug in the program.
> The error was 'BadWindow (invalid Window parameter)'.

This is just a shot in the dark but the way that the VTK integration
works is we give VTK the handle of the X-Window to draw upon and it then
deals with it at that low level. When an AUI pane is docked the
contents window is reparented to become a child of the managed docking
window instead of the floating window, and the floating window is
destroyed. So my guess is that either VTK is looking up at the parents
of the handle that is given to it, (and that parent is destroyed by
docking) or the reparenting process is altering the window handle given
to VTK in some way that conflicts with VTK.

The only suggestion I have is to try using an extra panel between the
AUI pane and the VTK window and see if that will insulate it enough to
avoid the problem.

--
Robin Dunn
Software Craftsmanhttp://wxPython.org