Error occur when placing two QVTKRenderWindowInteractor with vtkContextView in a single window

When I add two separate interactive vtkChartXY into a single window with PyQt5 and VTK. The window appears and works correctly. However, when it is closed there are several errors.

vtkWin32OpenGLRenderWin:758 ERR| vtkWin32OpenGLRenderWindow (00000254D385E180): failed to get valid pixel format. vtkOpenGLRenderWindow.c:511 ERR| vtkWin32OpenGLRenderWindow (00000254D385E180): GLEW could not be initialized: Missing GL version vtkOpenGLState.cxx:1795 WARN| Hardware does not support the number of textures defined. vtkOpenGLState.cxx:1795 WARN| Hardware does not support the number of textures defined. vtkOpenGLState.cxx:1795 WARN| Hardware does not support the number of textures defined. vtkOpenGLState.cxx:1795 WARN| Hardware does not support the number of textures defined. vtkOpenGLState.cxx:1795 WARN| Hardware does not support the number of textures defined. vtkOpenGLState.cxx:1795 WARN| Hardware does not support the number of textures defined. vtkOpenGLState.cxx:1795 WARN| Hardware does not support the number of textures defined.

The errors are similar to the post wglMakeCurrent failed in MakeCurrent after closed a window with two vtk widget., however, the problem still exists when there is vtkContextView.

Here is a demo:

from vtk import *
from vtkmodules.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from PyQt5 import QtWidgets


class ChartWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()

        layout = QtWidgets.QVBoxLayout()
        self.setLayout(layout)

        self.widget = QVTKRenderWindowInteractor(self)
        layout.addWidget(self.widget)

        chart = vtkChartXY()
        self.view = vtkContextView()
        self.view.SetRenderWindow(self.widget.GetRenderWindow())
        self.view.GetScene().AddItem(chart)

        # x-y plot
        f = vtkPiecewiseFunction()
        f.AddPoint(0, 0.0)
        f.AddPoint(500, 0.5)
        pf = vtkPiecewiseFunctionItem()
        pf.SetPiecewiseFunction(f)
        chart.AddPlot(pf)

        self.view.GetInteractor().Initialize()
        self.view.GetInteractor().Start()

    def closeEvent(self, event):
        super().closeEvent(event)
        self.widget.Finalize()


class MainWindow(QtWidgets.QWidget):

    def __init__(self):
        super().__init__()

        layout = QtWidgets.QHBoxLayout()
        self.setLayout(layout)

        self.w1 = ChartWidget()
        self.w2 = ChartWidget()
        layout.addWidget(self.w1)
        layout.addWidget(self.w2)

    def closeEvent(self, event):
        super().closeEvent(event)
        self.w1.close()
        self.w2.close()


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    app.exec_()

Hello,

The usual protocol in GUI programming is to forward events to the base class last, not first. For example, try changing this:

to this:

The same rationale applies to the other event-handling code in your program.

take care,

Paulo

Thanks Paulo! The errors seems still exist after the modification in the demo.

Hello,

Did you apply the expected event forwarding protocol to all your event handling code?

best,

PC

Actually, if only one widget was added in the demo codes, no error appears after closing the application window. But when two widgets (w1 and w2) were added, there are errors when closing.

Here is the modified code:

from vtk import *
from vtkmodules.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from PyQt5 import QtWidgets


class ChartWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()

        layout = QtWidgets.QVBoxLayout()
        self.setLayout(layout)

        self.widget = QVTKRenderWindowInteractor(self)
        layout.addWidget(self.widget)

        chart = vtkChartXY()
        self.view = vtkContextView()
        self.view.SetRenderWindow(self.widget.GetRenderWindow())
        self.view.GetScene().AddItem(chart)

        # x-y plot
        f = vtkPiecewiseFunction()
        f.AddPoint(0, 0.0)
        f.AddPoint(500, 0.5)
        pf = vtkPiecewiseFunctionItem()
        pf.SetPiecewiseFunction(f)
        chart.AddPlot(pf)

        self.view.GetInteractor().Initialize()
        self.view.GetInteractor().Start()


class MainWindow(QtWidgets.QWidget):

    def __init__(self):
        super().__init__()

        layout = QtWidgets.QHBoxLayout()
        self.setLayout(layout)

        self.w1 = ChartWidget()
        layout.addWidget(self.w1)
        
        self.w2 = ChartWidget()     # no error if these two lines were commented out.
        layout.addWidget(self.w2)   # no error if these two lines were commented out.


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    app.exec_()