[vtkusers] Segfault in vtkOpenGLRenderWindow.OpenGLInitState and advice about render window in/out events
Elvis Stansvik
elvis.stansvik at orexplore.com
Mon Jun 27 03:48:52 EDT 2016
2016-06-27 9:09 GMT+02:00 Elvis Stansvik <elvis.stansvik at orexplore.com>:
> 2016-06-26 13:31 GMT+02:00 Elvis Stansvik <elvis.stansvik at orexplore.com>:
>
>> 2016-06-26 13:06 GMT+02:00 Elvis Stansvik <elvis.stansvik at orexplore.com>:
>>
>>> Hi,
>>>
>>> In my quest to create a PyQt5 widget based on QOpenGLWidget for
>>> showing/interacting with VTK, I now have something that seems to work
>>> (including the whole thing as a runnable example below).
>>>
>>
>> It was a little too early to say "seems to work": When trying to show one
>> of the volumes I need to render, I get
>>
>> (gui) [estan at pyret orexplore.gui]$ python -m orexplore.gui.main
>> enabling depth test
>> ERROR: In
>> /home/estan/Blandat/vtk-python3/src/VTK-7.0.0/Rendering/OpenGL2/vtkOpenGLRenderWindow.cxx,
>> line 1682
>> vtkGenericOpenGLRenderWindow (0x308c3f0): Hardware does not support the
>> number of textures defined.
>>
>> Segmentation fault (core dumped)
>> (gui) [estan at pyret orexplore.gui]$
>>
>> on my Sandybridge laptop :/
>>
>> Anyone know if I'd be able to use the old OpenGL backend here?
>>
>
> I can now confirm that I'm getting the same error on my Haswell work
> laptop (which is using the OpenGL2 backend) :( Anyone know if there's a way
> to solve this or what I should look into?
>
> The volume I'm trying to render is not particularly big (2000x120x120,
> float), and it renders fine if I use a QGLWidget to back my VTK widget
> instead of QOpenGLWidget. So I'm suspecting it might have something to do
> with how I set up my QOpenGLWidget.
>
I tried printing the number of texture units in my StartEvent handler with
print(self.renderWindow.GetTextureUnitManager().GetNumberOfTextureUnits())
and it print 0, so I think something must definitely be wrong with how I
initialize things?
Elvis
>
> What I'm doing to configure it is simply:
>
> # Request OpenGL 3.2 compatibility profile and enable
> multi-sampling
> surfaceFormat = QSurfaceFormat.defaultFormat()
> surfaceFormat.setMajorVersion(3)
> surfaceFormat.setMinorVersion(2)
> surfaceFormat.setProfile(QSurfaceFormat.CompatibilityProfile)
> surfaceFormat.setSamples(8)
> self.setFormat(surfaceFormat)
>
> The whole reason I'm trying to get QOpenGLWidget working is that QGLWidget
> does not have a setFormat in PyQt5, since it doesn't wrap functions marked
> "obsolete" in Qt, and this prevents me from enabling multi-sampling.
>
> Very grateful for any advice from experts on the OpenGL2 backend, as I
> really need to get this working and move on.
>
> I'm attaching my vtk_widget2.py, which shows how I set up rendering into
> the QOpenGLWidget. Rendering of the cone example at the bottom works, it's
> just when I'm trying volume rendering using vtkGPUVolumeRayCastMapper that
> I get the above error.
>
> Elvis
>
>
>> Elvis
>>
>>
>>>
>>> I do however have two problems (indicated by "FIXME:"s in the code
>>> below):
>>>
>>> 1. When I try to call vtkOpenGLRenderWindow.OpenGLInitState when
>>> handling the render window StartEvent (commented out below), similar to how
>>> QVTKWidget2 does, I get a segmentation fault:
>>>
>>> (gdb) bt
>>> #0 0x0000000000000000 in ?? ()
>>> #1 0x00007fffd8ad13b9 in vtkOpenGLRenderWindow::OpenGLInitState() ()
>>> from /usr/lib/libvtkRenderingOpenGL2.so.1
>>> #2 0x00007fffd8de8479 in ?? () from
>>> /usr/lib/libvtkRenderingOpenGL2Python35D.so.1
>>> #3 0x00007ffff79ba5e9 in PyCFunction_Call () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #4 0x00007ffff7a325f1 in PyEval_EvalFrameEx () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #5 0x00007ffff7a339e2 in ?? () from /usr/lib/libpython3.5m.so.1.0
>>> #6 0x00007ffff7a33ac3 in PyEval_EvalCodeEx () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #7 0x00007ffff799db98 in ?? () from /usr/lib/libpython3.5m.so.1.0
>>> #8 0x00007ffff79730da in PyObject_Call () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #9 0x00007ffff7989d64 in ?? () from /usr/lib/libpython3.5m.so.1.0
>>> #10 0x00007ffff79730da in PyObject_Call () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #11 0x00007ffff7a2a457 in PyEval_CallObjectWithKeywords () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #12 0x00007fffe8d905a0 in vtkPythonCommand::Execute(vtkObject*, unsigned
>>> long, void*) () from /usr/lib/libvtkWrappingPython35Core.so.1
>>> #13 0x00007fffe89ac196 in ?? () from /usr/lib/libvtkCommonCore.so.1
>>> #14 0x00007fffdf022a0f in vtkRenderWindow::Render() () from
>>> /usr/lib/libvtkRenderingCore.so.1
>>> #15 0x00007fffd8ad4461 in vtkOpenGLRenderWindow::Render() () from
>>> /usr/lib/libvtkRenderingOpenGL2.so.1
>>> #16 0x00007fffdf027498 in vtkRenderWindowInteractor::Start() () from
>>> /usr/lib/libvtkRenderingCore.so.1
>>> #17 0x00007fffdf3ee789 in ?? () from
>>> /usr/lib/libvtkRenderingCorePython35D.so.1
>>> #18 0x00007ffff79ba5e9 in PyCFunction_Call () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #19 0x00007ffff7a325f1 in PyEval_EvalFrameEx () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #20 0x00007ffff7a339e2 in ?? () from /usr/lib/libpython3.5m.so.1.0
>>> #21 0x00007ffff7a33ac3 in PyEval_EvalCodeEx () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #22 0x00007ffff799db98 in ?? () from /usr/lib/libpython3.5m.so.1.0
>>> #23 0x00007ffff79730da in PyObject_Call () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #24 0x00007ffff7989d64 in ?? () from /usr/lib/libpython3.5m.so.1.0
>>> #25 0x00007ffff79730da in PyObject_Call () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #26 0x00007ffff79cfa10 in ?? () from /usr/lib/libpython3.5m.so.1.0
>>> #27 0x00007ffff79cdde6 in ?? () from /usr/lib/libpython3.5m.so.1.0
>>> #28 0x00007ffff79730da in PyObject_Call () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #29 0x00007ffff7a2c4bc in PyEval_EvalFrameEx () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #30 0x00007ffff7a32942 in PyEval_EvalFrameEx () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #31 0x00007ffff7a339e2 in ?? () from /usr/lib/libpython3.5m.so.1.0
>>> #32 0x00007ffff7a33ac3 in PyEval_EvalCodeEx () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #33 0x00007ffff7a33aeb in PyEval_EvalCode () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #34 0x00007ffff7a2802d in ?? () from /usr/lib/libpython3.5m.so.1.0
>>> #35 0x00007ffff79ba5e9 in PyCFunction_Call () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #36 0x00007ffff7a325f1 in PyEval_EvalFrameEx () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #37 0x00007ffff7a339e2 in ?? () from /usr/lib/libpython3.5m.so.1.0
>>> #38 0x00007ffff7a306e0 in PyEval_EvalFrameEx () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #39 0x00007ffff7a339e2 in ?? () from /usr/lib/libpython3.5m.so.1.0
>>> #40 0x00007ffff7a33ac3 in PyEval_EvalCodeEx () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #41 0x00007ffff799db98 in ?? () from /usr/lib/libpython3.5m.so.1.0
>>> #42 0x00007ffff79730da in PyObject_Call () from
>>> /usr/lib/libpython3.5m.so.1.0
>>> #43 0x00007ffff7a6af01 in ?? () from /usr/lib/libpython3.5m.so.1.0
>>> #44 0x00007ffff7a6b7dc in Py_Main () from /usr/lib/libpython3.5m.so.1.0
>>> #45 0x0000000000400ae7 in main ()
>>> (gdb)
>>>
>>> Sorry for the lack of debugging symbols, but before I recompile VTK with
>>> debugging symbols, I thought I'd ask if anyone has an idea what may be the
>>> reason for the crash? I haven't seen any adverse effects from not calling
>>> this function, but I suspect something is broken? (how can I test?)
>>>
>>> 2. I can't seem to find a way to properly implement the
>>> WindowIsCurrentEvent, WindowIsDirectEvent and WindowSupportsOpenGLEvent
>>> render window events. E.g. (from below):
>>>
>>> def _onWindowIsCurrentEvent(self, sender, event, callData):
>>> callData = True # FIXME: This won't work...
>>>
>>> def _onWindowIsDirectEvent(self, sender, event, callData):
>>> callData = True # FIXME: This won't work...
>>>
>>> def _onWindowSupportsOpenGLEvent(self, sender, event, callData):
>>> callData = True # FIXME: This won't work...
>>>
>>> The callData is a bool* and the handler is expected to write a bool to
>>> the pointed memory. I can't see that there's any way to do this from Python
>>> (is it possible with ctypes somehow?).
>>>
>>> So far I haven't seen any adverse effects from not implementing these
>>> three events correctly, but expect something to be broken..?
>>>
>>> Thankful for any advice on these two issues, and it would be great if
>>> someone could try out the example, with the
>>>
>>> # self.renderWindow.OpenGLInitState() # FIXME: Segfaults :(
>>>
>>> line uncommented, to confirm the segfault I'm seeing.
>>>
>>> Cheers,
>>> Elvis
>>>
>>>
>>> from PyQt5.QtCore import Qt, QTimer, QEvent, QSize
>>> from PyQt5.QtGui import QSurfaceFormat
>>> from PyQt5.QtWidgets import QWidget, QOpenGLWidget
>>>
>>> from vtk import vtkGenericOpenGLRenderWindow
>>> from vtk import vtkGenericRenderWindowInteractor
>>> from vtk import vtkCommand
>>> from vtk import vtkRenderer
>>>
>>> from vtk import VTK_CURSOR_DEFAULT, VTK_CURSOR_ARROW, VTK_CURSOR_SIZENE
>>> from vtk import VTK_CURSOR_SIZENW, VTK_CURSOR_SIZESW, VTK_CURSOR_SIZESE
>>> from vtk import VTK_CURSOR_SIZENS, VTK_CURSOR_SIZEWE, VTK_CURSOR_SIZEALL
>>> from vtk import VTK_CURSOR_HAND, VTK_CURSOR_CROSSHAIR
>>>
>>>
>>> class VTKWidget(QOpenGLWidget):
>>>
>>> def __init__(self, surfaceFormat=QSurfaceFormat.defaultFormat(),
>>> *args, **kwargs):
>>> super().__init__(*args, **kwargs)
>>>
>>> # Request OpenGL 3.2 compatibility profile and enable
>>> multi-sampling
>>> surfaceFormat.setMajorVersion(3)
>>> surfaceFormat.setMinorVersion(2)
>>> surfaceFormat.setProfile(QSurfaceFormat.CompatibilityProfile)
>>> surfaceFormat.setSamples(8)
>>> self.setFormat(surfaceFormat)
>>>
>>> # Create render window
>>> self.renderWindow = vtkGenericOpenGLRenderWindow()
>>> self.renderWindow.SetSize(self.width(), self.height())
>>> self.renderWindow.SetPosition(self.x(), self.y())
>>>
>>> self.renderWindow.AddObserver(vtkCommand.StartEvent,
>>> self._onStartEvent)
>>> self.renderWindow.AddObserver(vtkCommand.EndEvent,
>>> self._onEndEvent)
>>> self.renderWindow.AddObserver(vtkCommand.CursorChangedEvent,
>>> self._onCursorChangedEvent)
>>> self.renderWindow.AddObserver(vtkCommand.WindowMakeCurrentEvent,
>>> self._onWindowMakeCurrentEvent)
>>> self.renderWindow.AddObserver(vtkCommand.WindowIsCurrentEvent,
>>> self._onWindowIsCurrentEvent)
>>> self.renderWindow.AddObserver(vtkCommand.WindowFrameEvent,
>>> self._onWindowFrameEvent)
>>> self.renderWindow.AddObserver(vtkCommand.WindowIsDirectEvent,
>>> self._onWindowIsDirectEvent)
>>>
>>> self.renderWindow.AddObserver(vtkCommand.WindowSupportsOpenGLEvent,
>>> self._onWindowSupportsOpenGLEvent)
>>>
>>> # Create interactor
>>> self.interactor = vtkGenericRenderWindowInteractor()
>>> self.interactor.SetRenderWindow(self.renderWindow)
>>> self.interactor.SetSize(self.width(), self.height())
>>> self.interactor.AddObserver(vtkCommand.CreateTimerEvent,
>>> lambda *_: self._timer.start(10))
>>> self.interactor.AddObserver(vtkCommand.DestroyTimerEvent,
>>> lambda *_: self._timer.stop())
>>> self.interactor.Start()
>>>
>>> # Create renderer
>>> self.renderer = vtkRenderer()
>>> self.renderWindow.AddRenderer(self.renderer)
>>>
>>> # Timer for the interactor
>>> self._timer = QTimer(self)
>>> self._timer.timeout.connect(self.interactor.TimerEvent)
>>>
>>> # Some tracked input state
>>> self._pressedButton = Qt.NoButton
>>> self._lastMouseX = 0
>>> self._lastMouseY = 0
>>> self._lastModifiers = Qt.NoModifier
>>> self._lastButtons = Qt.NoButton
>>> self._wheelDelta = 0
>>>
>>> # Finalize render window before we're destroyed
>>> self._hidden = QWidget(self)
>>> self._hidden.hide()
>>> self._hidden.destroyed.connect(self.renderWindow.Finalize)
>>>
>>> #
>>> # Handle VTK render window events
>>> #
>>>
>>> def _onStartEvent(self, *_):
>>> self.makeCurrent()
>>> self.renderWindow.PushState()
>>> # self.renderWindow.OpenGLInitState() # FIXME: Segfaults :(
>>>
>>> def _onEndEvent(self, *_):
>>> self.renderWindow.PopState()
>>>
>>> def _onWindowMakeCurrentEvent(self, *_):
>>> pass # Handled automatically by QOpenGLWidget
>>>
>>> def _onWindowIsCurrentEvent(self, sender, event, callData):
>>> callData = True # FIXME: This won't work...
>>>
>>> def _onWindowIsDirectEvent(self, sender, event, callData):
>>> callData = True # FIXME: This won't work...
>>>
>>> def _onWindowSupportsOpenGLEvent(self, sender, event, callData):
>>> callData = True # FIXME: This won't work...
>>>
>>> def _onWindowFrameEvent(self, *_):
>>> if self.renderWindow.GetSwapBuffers():
>>> self.update()
>>>
>>> def _onCursorChangedEvent(self):
>>>
>>> def showCursor():
>>> vtkCursor = self.renderWindow.GetCurrentCursor()
>>> qtCursor = VTKWidget._cursors.get(vtkCursor, Qt.ArrowCursor)
>>> self.setCursor(qtCursor)
>>>
>>> # Defer until cursor has actually changed
>>> QTimer.singleShot(0, showCursor)
>>>
>>> #
>>> # Implement QOpenGLWidget functions
>>> #
>>>
>>> def initializeGL(self):
>>> self.renderWindow.OpenGLInitContext()
>>>
>>> def paintGL(self):
>>> self.interactor.Render()
>>>
>>> def resizeGL(self, width, height):
>>> self.renderWindow.SetSize(width, height)
>>> self.interactor.SetSize(width, height)
>>> self.interactor.ConfigureEvent()
>>>
>>> #
>>> # Handle QWidget events
>>> #
>>>
>>> def closeEvent(self, _):
>>> self.renderWindow.Finalize()
>>>
>>> def sizeHint(self):
>>> return QSize(400, 400)
>>>
>>> def moveEvent(self, event):
>>> super().moveEvent(event)
>>> self.renderWindow.SetPosition(self.x(), self.y())
>>>
>>> def enterEvent(self, event):
>>> ctrl, shift = self._modifiers(event)
>>> self.interactor.SetEventInformationFlipY(self._lastMouseX,
>>> self._lastMouseY,
>>> ctrl, shift, chr(0), 0,
>>> None)
>>> self.interactor.EnterEvent()
>>>
>>> def leaveEvent(self, event):
>>> ctrl, shift = self._modifiers(event)
>>> self.interactor.SetEventInformationFlipY(self._lastMouseX,
>>> self._lastMouseY,
>>> ctrl, shift, chr(0), 0,
>>> None)
>>> self.interactor.LeaveEvent()
>>>
>>> def mousePressEvent(self, event):
>>> ctrl, shift = self._modifiers(event)
>>> repeat = 1 if event.type() == QEvent.MouseButtonDblClick else 0
>>> self.interactor.SetEventInformationFlipY(event.x(), event.y(),
>>> ctrl, shift,
>>> chr(0), repeat, None)
>>>
>>> self._pressedButton = event.button()
>>>
>>> if self._pressedButton == Qt.LeftButton:
>>> self.interactor.LeftButtonPressEvent()
>>> elif self._pressedButton == Qt.RightButton:
>>> self.interactor.RightButtonPressEvent()
>>> elif self._pressedButton == Qt.MidButton:
>>> self.interactor.MiddleButtonPressEvent()
>>>
>>> def mouseReleaseEvent(self, event):
>>> ctrl, shift = self._modifiers(event)
>>> self.interactor.SetEventInformationFlipY(event.x(), event.y(),
>>> ctrl, shift,
>>> chr(0), 0, None)
>>>
>>> if self._pressedButton == Qt.LeftButton:
>>> self.interactor.LeftButtonReleaseEvent()
>>> elif self._pressedButton == Qt.RightButton:
>>> self.interactor.RightButtonReleaseEvent()
>>> elif self._pressedButton == Qt.MidButton:
>>> self.interactor.MiddleButtonReleaseEvent()
>>>
>>> self._pressedButton = Qt.NoButton
>>>
>>> def mouseMoveEvent(self, event):
>>> self._lastModifiers = event.modifiers()
>>> self._lastButtons = event.buttons()
>>> self._lastMouseX = event.x()
>>> self._lastMouseY = event.y()
>>>
>>> ctrl, shift = self._modifiers(event)
>>> self.interactor.SetEventInformationFlipY(event.x(), event.y(),
>>> ctrl, shift,
>>> chr(0), 0, None)
>>> self.interactor.MouseMoveEvent()
>>>
>>> def keyPressEvent(self, event):
>>> ctrl, shift = self._modifiers(event)
>>> key = str(event.text()) if event.key() < 256 else chr(0)
>>> keySym = VTKWidget._qtKeyToKeySymbol(event.key())
>>>
>>> if shift and len(keySym) == 1 and keySym.isalpha():
>>> keySym = keySym.upper()
>>>
>>> self.interactor.SetEventInformationFlipY(self._lastMouseX,
>>> self._lastMouseY,
>>> ctrl, shift, key, 0,
>>> keySym)
>>> self.interactor.KeyPressEvent()
>>> self.interactor.CharEvent()
>>>
>>> def keyReleaseEvent(self, event):
>>> ctrl, shift = self._modifiers(event)
>>> key = chr(event.key()) if event.key() < 256 else chr(0)
>>>
>>> self.interactor.SetEventInformationFlipY(self._lastMouseX,
>>> self._lastMouseY,
>>> ctrl, shift, key, 0,
>>> None)
>>> self.interactor.KeyReleaseEvent()
>>>
>>> def wheelEvent(self, event):
>>> self._wheelDelta += event.angleDelta().y()
>>>
>>> if self._wheelDelta >= 120:
>>> self.interactor.MouseWheelForwardEvent()
>>> self._wheelDelta = 0
>>> elif self._wheelDelta <= -120:
>>> self.interactor.MouseWheelBackwardEvent()
>>> self._wheelDelta = 0
>>>
>>> def _modifiers(self, event):
>>> ctrl = shift = False
>>>
>>> if hasattr(event, 'modifiers'):
>>> if event.modifiers() & Qt.ShiftModifier:
>>> shift = True
>>> if event.modifiers() & Qt.ControlModifier:
>>> ctrl = True
>>> else:
>>> if self._lastModifiers & Qt.ShiftModifier:
>>> shift = True
>>> if self._lastModifiers & Qt.ControlModifier:
>>> ctrl = True
>>>
>>> return ctrl, shift
>>>
>>> @classmethod
>>> def _qtKeyToKeySymbol(cls, key):
>>> if key not in VTKWidget._keySymbols:
>>> return None
>>> return VTKWidget._keySymbols[key]
>>>
>>> # Maps VTK cursors to Qt cursors
>>> _cursors = {
>>> VTK_CURSOR_DEFAULT: Qt.ArrowCursor,
>>> VTK_CURSOR_ARROW: Qt.ArrowCursor,
>>> VTK_CURSOR_SIZENE: Qt.SizeBDiagCursor,
>>> VTK_CURSOR_SIZENW: Qt.SizeFDiagCursor,
>>> VTK_CURSOR_SIZESW: Qt.SizeBDiagCursor,
>>> VTK_CURSOR_SIZESE: Qt.SizeFDiagCursor,
>>> VTK_CURSOR_SIZENS: Qt.SizeVerCursor,
>>> VTK_CURSOR_SIZEWE: Qt.SizeHorCursor,
>>> VTK_CURSOR_SIZEALL: Qt.SizeAllCursor,
>>> VTK_CURSOR_HAND: Qt.PointingHandCursor,
>>> VTK_CURSOR_CROSSHAIR: Qt.CrossCursor
>>> }
>>>
>>> # Maps Qt keys to VTK key symbols
>>> _keySymbols = {
>>> Qt.Key_Backspace: 'BackSpace',
>>> Qt.Key_Tab: 'Tab',
>>> Qt.Key_Backtab: 'Tab',
>>> # Qt.Key_Clear : 'Clear',
>>> Qt.Key_Return: 'Return',
>>> Qt.Key_Enter: 'Return',
>>> Qt.Key_Shift: 'Shift_L',
>>> Qt.Key_Control: 'Control_L',
>>> Qt.Key_Alt: 'Alt_L',
>>> Qt.Key_Pause: 'Pause',
>>> Qt.Key_CapsLock: 'Caps_Lock',
>>> Qt.Key_Escape: 'Escape',
>>> Qt.Key_Space: 'space',
>>> # Qt.Key_Prior : 'Prior',
>>> # Qt.Key_Next : 'Next',
>>> Qt.Key_End: 'End',
>>> Qt.Key_Home: 'Home',
>>> Qt.Key_Left: 'Left',
>>> Qt.Key_Up: 'Up',
>>> Qt.Key_Right: 'Right',
>>> Qt.Key_Down: 'Down',
>>> Qt.Key_SysReq: 'Snapshot',
>>> Qt.Key_Insert: 'Insert',
>>> Qt.Key_Delete: 'Delete',
>>> Qt.Key_Help: 'Help',
>>> Qt.Key_0: '0',
>>> Qt.Key_1: '1',
>>> Qt.Key_2: '2',
>>> Qt.Key_3: '3',
>>> Qt.Key_4: '4',
>>> Qt.Key_5: '5',
>>> Qt.Key_6: '6',
>>> Qt.Key_7: '7',
>>> Qt.Key_8: '8',
>>> Qt.Key_9: '9',
>>> Qt.Key_A: 'a',
>>> Qt.Key_B: 'b',
>>> Qt.Key_C: 'c',
>>> Qt.Key_D: 'd',
>>> Qt.Key_E: 'e',
>>> Qt.Key_F: 'f',
>>> Qt.Key_G: 'g',
>>> Qt.Key_H: 'h',
>>> Qt.Key_I: 'i',
>>> Qt.Key_J: 'j',
>>> Qt.Key_K: 'k',
>>> Qt.Key_L: 'l',
>>> Qt.Key_M: 'm',
>>> Qt.Key_N: 'n',
>>> Qt.Key_O: 'o',
>>> Qt.Key_P: 'p',
>>> Qt.Key_Q: 'q',
>>> Qt.Key_R: 'r',
>>> Qt.Key_S: 's',
>>> Qt.Key_T: 't',
>>> Qt.Key_U: 'u',
>>> Qt.Key_V: 'v',
>>> Qt.Key_W: 'w',
>>> Qt.Key_X: 'x',
>>> Qt.Key_Y: 'y',
>>> Qt.Key_Z: 'z',
>>> Qt.Key_Asterisk: 'asterisk',
>>> Qt.Key_Plus: 'plus',
>>> Qt.Key_Minus: 'minus',
>>> Qt.Key_Period: 'period',
>>> Qt.Key_Slash: 'slash',
>>> Qt.Key_F1: 'F1',
>>> Qt.Key_F2: 'F2',
>>> Qt.Key_F3: 'F3',
>>> Qt.Key_F4: 'F4',
>>> Qt.Key_F5: 'F5',
>>> Qt.Key_F6: 'F6',
>>> Qt.Key_F7: 'F7',
>>> Qt.Key_F8: 'F8',
>>> Qt.Key_F9: 'F9',
>>> Qt.Key_F10: 'F10',
>>> Qt.Key_F11: 'F11',
>>> Qt.Key_F12: 'F12',
>>> Qt.Key_F13: 'F13',
>>> Qt.Key_F14: 'F14',
>>> Qt.Key_F15: 'F15',
>>> Qt.Key_F16: 'F16',
>>> Qt.Key_F17: 'F17',
>>> Qt.Key_F18: 'F18',
>>> Qt.Key_F19: 'F19',
>>> Qt.Key_F20: 'F20',
>>> Qt.Key_F21: 'F21',
>>> Qt.Key_F22: 'F22',
>>> Qt.Key_F23: 'F23',
>>> Qt.Key_F24: 'F24',
>>> Qt.Key_NumLock: 'Num_Lock',
>>> Qt.Key_ScrollLock: 'Scroll_Lock'
>>> }
>>>
>>> def example():
>>> #
>>> # Try out VTKWidget by showing a couple of cones
>>> #
>>> from sys import argv, exit
>>> from PyQt5.QtWidgets import QApplication, QVBoxLayout
>>> from vtk import vtkConeSource, vtkPolyDataMapper, vtkActor
>>>
>>> app = QApplication(argv)
>>>
>>> layout = QVBoxLayout()
>>>
>>> for i in range(2):
>>> widget = VTKWidget()
>>>
>>> coneSource = vtkConeSource()
>>> coneSource.SetResolution(8)
>>>
>>> coneMapper = vtkPolyDataMapper()
>>> coneMapper.SetInputConnection(coneSource.GetOutputPort())
>>>
>>> coneActor = vtkActor()
>>> coneActor.SetMapper(coneMapper)
>>>
>>> widget.renderer.AddActor(coneActor)
>>>
>>> layout.addWidget(widget)
>>>
>>> container = QWidget()
>>> container.setLayout(layout)
>>> container.show()
>>>
>>> exit(app.exec_())
>>>
>>>
>>> if __name__ == '__main__':
>>> example()
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20160627/d300bba5/attachment-0001.html>
More information about the vtkusers
mailing list