Commit 5316dff1 authored by Félix C. Morency's avatar Félix C. Morency Committed by Dave DeMarle
Browse files

BUG: Fix GLXBadDrawable when using multiple QVTKRenderWindowInteractor

The vtkRenderWindow was never finalized which caused GLXBadDrawable
errors on application exit if using multiple QVTKRenderWindowInteractor.
This patch provides a cleanup mechanism to finalize the vtkRenderWindow
before its destruction/close preventing GLXBadDrawable errors. This
patch works in both embedded and non-embedded cases.

This patch also provides a test case for QVTKRenderWindowInteractor.

DDM: commit manufactured to force dashboard tests

Change-Id: Ie86d17fe7648868f8f1d5e4b00f52419d5f35a5b
parent 1b9c1ee3
#!/usr/bin/env python
import sys
import os
try:
from PyQt4 import QtCore, QtGui
except ImportError:
try:
from PySide import QtCore, QtGui
except ImportError as err:
raise ImportError("Cannot load either PyQt or PySide")
import vtk
from vtk.qt4.QVTKRenderWindowInteractor import *
from vtk.test import Testing
class TestQVTKRenderWindowInteractor(Testing.vtkTest):
def testQVTKRenderWindowInteractor(self):
w2 = QVTKRenderWindowInteractor()
ren = vtk.vtkRenderer()
ren.SetBackground(0,0,0)
ren.SetBackground2(1,1,1)
ren.SetGradientBackground(1)
renwin = w2.GetRenderWindow()
cone = vtk.vtkConeSource()
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(cone.GetOutputPort())
actor = vtk.vtkActor()
actor.SetMapper(mapper)
ren.AddViewProp(actor)
ren.ResetCamera()
w2.show()
if Testing.isInteractive():
QtGui.qApp.exec_()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
Testing.main([(TestQVTKRenderWindowInteractor, 'test')])
......@@ -33,6 +33,10 @@ try:
except ImportError:
try:
from PySide import QtCore, QtGui
#PyQt4 signal/slot compatibility
QtCore.pyqtSignal = QtCore.Signal
QtCore.pyqtSlot = QtCore.Slot
except ImportError as err:
raise ImportError("Cannot load either PyQt or PySide")
import vtk
......@@ -182,6 +186,13 @@ class QVTKRenderWindowInteractor(QtGui.QWidget):
self._Iren.GetRenderWindow().AddObserver('CursorChangedEvent',
self.CursorChangedEvent)
#Create a hidden child widget and connect its destroyed signal to its
#parent ``Finalize`` slot. The hidden children will be destroyed before
#its parent thus allowing cleanup of VTK elements.
self._hidden = QtGui.QWidget(self)
self._hidden.hide()
self._hidden.destroyed.connect(self.Finalize)
def __getattr__(self, attr):
"""Makes the object behave like a vtkGenericRenderWindowInteractor"""
if attr == '__vtk__':
......@@ -192,6 +203,13 @@ class QVTKRenderWindowInteractor(QtGui.QWidget):
raise AttributeError, self.__class__.__name__ + \
" has no attribute named " + attr
@QtCore.pyqtSlot()
def Finalize(self):
'''
Call internal cleanup method on VTK objects
'''
self._RenderWindow.Finalize()
def CreateTimer(self, obj, evt):
self._Timer.start(10)
......@@ -219,6 +237,9 @@ class QVTKRenderWindowInteractor(QtGui.QWidget):
qt_cursor = self._CURSOR_MAP.get(vtk_cursor, QtCore.Qt.ArrowCursor)
self.setCursor(qt_cursor)
def closeEvent(self, evt):
self.Finalize()
def sizeHint(self):
return QtCore.QSize(400, 400)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment