[vtkusers] Using context views in a QVTKRenderWindowInteractor from Python

Elvis Stansvik elvis.stansvik at orexplore.com
Mon May 23 12:43:06 EDT 2016


Den 23 maj 2016 5:28 em skrev "Elvis Stansvik" <elvis.stansvik at orexplore.com
>:
>
> 2016-05-23 16:55 GMT+02:00 Elvis Stansvik <elvis.stansvik at orexplore.com>:
>>
>> 2016-05-23 16:28 GMT+02:00 Elvis Stansvik <elvis.stansvik at orexplore.com>:
>>>
>>> I'm trying to use a context view (my goal is to show an XYChart) inside
a QVTKRenderWindowInteractor, but I'm struggling to get the initialization
of render window / interactor right.
>>>
>>> The docs for vtkRenderViewBase (base class for vtkContextView) says:
>>>
>>> "In order to use the view with a QVTKWidget the following code is
required to ensure the interactor and render window are initialized
properly.
>>>
>>> QVTKWidget *widget = new QVTKWidget;
>>> vtkContextView *view = vtkContextView::New();
>>> view->SetInteractor(widget->GetInteractor());
>>> widget->SetRenderWindow(view->GetRenderWindow());"
>>>
>>> but this is about QVTKWidget, the C++ widget class, which is quite
different from the Python QVTKRenderWindowInteractor class.
>>>
>>> My failed attempt to recreate this initialization sequence when using
QVTKRenderWindowInteractor is this:
>>>
>>>
>>> class TestWidget(QVTKRenderWindowInteractor):
>>>
>>>     def __init__(self, parent=None):
>>>
>>>         # We need a render window and interactor to pass to
>>>         # QVTKRenderWindowInteractor constructor.
>>>         self.renderWindow = vtkRenderWindow()
>>>         self.interactor = vtkGenericRenderWindowInteractor()
>>>         self.interactor.SetRenderWindow(self.renderWindow)
>>>
>>>         super(TestWidget, self).__init__(
>>>             parent, rw=self.renderWindow, iren=self.interactor)
>>>
>>>         # Create a context view and set it to use the same
>>>         # interactor as the QVTKRenderWindowInteractor.
>>>         self.contextView = vtkContextView()
>>>         self.contextView.SetInteractor(self.interactor)
>>>
>>>         # Create chart and add it to the scene of the context view.
>>>         self.chart = vtkChartXY()
>>>         self.contextView.GetScene().AddItem(self.chart)
>>>
>>>         # Initialize and start.
>>>         self.Initialize()
>>>         self.Start()
>>>
>>>
>>> if __name__ == '__main__':
>>>
>>>     app = QApplication(argv)
>>>
>>>     widget = TestWidget()
>>>     widget.show()
>>>
>>>     exit(app.exec_())
>>>
>>>
>>> But something goes wrong here, because two windows show up (see
attached screenshot). The application also segfaults on exit. Besides, it
looks very kludgy to have to do stuff before the call to super() here. Is
this really the right way to use the API?

For full disclosure: This is with Qt 5.5.1 and VTK 6 (not sure if 6.2 or
6.3, on the bus atm), on Kubuntu 16.04.

Elvis
>>>
>>> If anyone has worked with QVTKRenderWindowInteractor and
vtkContextView, I'd much appriciate some advice.
>>
>>
>> Inspired by an older post on this subject [1], I was able to get it
partly working with:
>>
>> class TestWidget(QVTKRenderWindowInteractor):
>>
>>     def __init__(self, parent=None):
>>         super(TestWidget, self).__init__(parent)
>>
>>         self.contextView = vtkContextView()
>>         self.chart = vtkChartXY()
>>         self.contextView.GetScene().AddItem(self.chart)
>>
>>         # Add renderer of context view to the render window of the
widget.
>>
self.GetRenderWindow().AddRenderer(self.contextView.GetRenderer())
>>
>>         self.Initialize()
>>         self.Start()
>>
>> The chart is empty here, but I've verified by adding some items to it
that it at least shows up correctly, in a single window.
>>
>> The problem is that interaction of course doesn't work, and if I also add
>>
>>         self.contextView.SetInteractor(self._Iren)
>>
>> to set the interactor of the context view to the
vtkGenericRenderWindowInteractor backing the QVTKRenderWindowInteractor,
I'm back to the problem with two windows showing up.
>>
>> I need interaction to work, because my goal is to show an opacity
function editor item in the chart.
>>
>> Thankful for any and all advice!
>
>
> To better illustrate, here's the scatter plot Python example from the
wiki, with the code I've added to try to make it work with
QVTKRenderWindowInteractor.
>
> The result is that when the application is executed, a "Visualization
Toolkit - OpenGL" window first shows up, where interaction works fine. This
is not the Qt window though. The Qt window shows up if I close the first
window, and interaction does not work (try hovering the data points).
>
> How would this example need to be modified for it to work? (chart shown
in the Qt window, with interaction working).
>
> Best regards,
> Elvis
>
> # <ADDED>
> app = QApplication(sys.argv)
>
> widget = QVTKRenderWindowInteractor()
> widget.Initialize()
> widget.Start()
> # </ADDED>
>
> view = vtk.vtkContextView()
> view.GetRenderer().SetBackground(1.0, 1.0, 1.0)
> view.GetRenderWindow().SetSize(400, 300)
>
> chart = vtk.vtkChartXY()
> view.GetScene().AddItem(chart)
> chart.SetShowLegend(True)
>
> table = vtk.vtkTable()
>
> arrX = vtk.vtkFloatArray()
> arrX.SetName('X Axis')
>
> arrC = vtk.vtkFloatArray()
> arrC.SetName('Cosine')
>
> arrS = vtk.vtkFloatArray()
> arrS.SetName('Sine')
>
> arrT = vtk.vtkFloatArray()
> arrT.SetName('Sine-Cosine')
>
> table.AddColumn(arrC)
> table.AddColumn(arrS)
> table.AddColumn(arrX)
> table.AddColumn(arrT)
>
> numPoints = 40
>
> inc = 7.5 / (numPoints - 1)
> table.SetNumberOfRows(numPoints)
> for i in range(numPoints):
>     table.SetValue(i, 0, i * inc)
>     table.SetValue(i, 1, math.cos(i * inc))
>     table.SetValue(i, 2, math.sin(i * inc))
>     table.SetValue(i, 3, math.sin(i * inc) - math.cos(i * inc))
>
> points = chart.AddPlot(vtk.vtkChart.POINTS)
> points.SetInputData(table, 0, 1)
> points.SetColor(0, 0, 0, 255)
> points.SetWidth(1.0)
> points.SetMarkerStyle(vtk.vtkPlotPoints.CROSS)
>
> points = chart.AddPlot(vtk.vtkChart.POINTS)
> points.SetInputData(table, 0, 2)
> points.SetColor(0, 0, 0, 255)
> points.SetWidth(1.0)
> points.SetMarkerStyle(vtk.vtkPlotPoints.PLUS)
>
> points = chart.AddPlot(vtk.vtkChart.POINTS)
> points.SetInputData(table, 0, 3)
> points.SetColor(0, 0, 255, 255)
> points.SetWidth(1.0)
> points.SetMarkerStyle(vtk.vtkPlotPoints.CIRCLE)
>
> view.GetRenderWindow().SetMultiSamples(0)
> view.GetInteractor().Initialize()
> view.GetInteractor().Start()
>
> # <ADDED>
> widget.GetRenderWindow().AddRenderer(view.GetRenderer())
> widget.setWindowTitle('Qt Widget')
> widget.show()
>
> exit(app.exec_())
> # </ADDED>
>
>>
>>
>> Elvis
>>
>> [1] http://www.vtk.org/pipermail/vtkusers/2011-July/068893.html
>>
>>>
>>>
>>> Cheers,
>>> Elvis
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20160523/2c716d9c/attachment.html>


More information about the vtkusers mailing list