Vedo: creating a renderer in qt fails for some axes types

Created on 20 Jun 2019  路  3Comments  路  Source: marcomusy/vedo

When embedding a plotter in a qt application, plotter.show() needs to be called to create a renderer instance.

This call fails for some axes types, among which the default axes=4.

Naamloos

import sys
from PyQt5 import Qt
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor

from vtkplotter import Plotter, Cube, Torus, Cone, settings

settings.usingQt = True


class MainWindow(Qt.QMainWindow):
    def __init__(self, parent=None):

        Qt.QMainWindow.__init__(self, parent)
        self.frame = Qt.QFrame()
        self.vl = Qt.QVBoxLayout()
        self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
        self.vl.addWidget(self.vtkWidget)

        # vp = Plotter(offscreen=True, interactive=False, axes=2) # <== works
        vp = Plotter(offscreen=True, interactive=False, axes=4) # <== fails

        vp += Cone()

        vp.show()  # to create renderer

        # further setup here - omitted for clarity 

        self.show() # <-- just to be able to close the application

if __name__ == "__main__":
    app = Qt.QApplication(sys.argv)
    window = MainWindow()
app.exec_()
bug

Most helpful comment

Idea:

pass the
vtkWidget (QVTKRenderWindowInteractor) as an argument when creating the Plotter.

vp = Plotter(qtWidget = vtkWidget)

then the plotter can

  • override of "offscreen" and "interactive" settings
  • set self.interactor

in Plotter.show():

  • assign the newly created renderer to the widget
  • add the axis :-)

Marco, if you like this then I can implement it and create a merge request for it.

All 3 comments

some more information:

The error occurs in addons.py in the function addIcon()
The root cause is that the orientation type widget can not be enabled without a interactor set. (line 637: widget.EnabledOn()
Also, the interactor needs to have a the rendered assigned.

A work-around is to skip the creation of axis on creation and add them manually later.
This needs to be done after adding the renderer to the widget.


        self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()  # create interactor here

        vp = Plotter(offscreen=True, interactive=False, axes=0) # <== No axes
        vp += Cone()
        vp.show()  # to create renderer

        # assign the renderer
        self.vtkWidget.GetRenderWindow().AddRenderer(vp.renderer)

        # set interactor and create axes "manually"
        vp.interactor = self.iren
        vp.addAxes(4)

Idea:

pass the
vtkWidget (QVTKRenderWindowInteractor) as an argument when creating the Plotter.

vp = Plotter(qtWidget = vtkWidget)

then the plotter can

  • override of "offscreen" and "interactive" settings
  • set self.interactor

in Plotter.show():

  • assign the newly created renderer to the widget
  • add the axis :-)

Marco, if you like this then I can implement it and create a merge request for it.

Yup! That is a very nice idea!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

CMengich picture CMengich  路  5Comments

jrdkr picture jrdkr  路  7Comments

Yoorthiziri picture Yoorthiziri  路  7Comments

Jesse0818 picture Jesse0818  路  4Comments

MarkusRosen picture MarkusRosen  路  5Comments