Qt widgets over the QVTKWidget in Python: no transparency

Hi,

I can put Qt widgets over the VTK widget in Python, but a few stange things happen when I do.

  1. Transparency doesn’t work.
  2. The color changes slowly when moving the mouse cursor over the button and reset only when resizing the window.

I have tried both PyQT and PySide2 with different versions, inclusing the latest. I also tried with both VTK 8.2 and 9.0. I have seen working examples, but so far, not in Python.

The following code is my example. The button should be transparent. If it works on your end, then it could be specific to my os/hardware.

import sys, os
import vtk
from PyQt5 import QtCore, QtWidgets, QtGui
import PyQt5
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor

dirname = os.path.dirname(PyQt5.__file__)
plugin_path = os.path.join(dirname, 'plugins', 'platforms')
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = plugin_path


class MainWindow(QtWidgets.QMainWindow):

    def __init__(self, parent=None):
        QtWidgets.QMainWindow.__init__(self, parent)

        self.widget = QtWidgets.QWidget()
        self.vl = QtWidgets.QVBoxLayout()
        self.vtkWidget = QVTKRenderWindowInteractor(self.widget)
        self.vl.addWidget(self.vtkWidget)

        self.ren = vtk.vtkRenderer()
        self.vtkWidget.GetRenderWindow().AddRenderer(self.ren)
        self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()

        self.layout = QtWidgets.QHBoxLayout()
        self.vtkWidget.setLayout(self.layout)
        btn = QtWidgets.QPushButton("TEST TEST", self.vtkWidget)
        btn.setStyleSheet("background-color: rgba(255,0,255,128)")
        self.layout.addWidget(btn)

        # Create source
        source = vtk.vtkSphereSource()
        source.SetCenter(0, 0, 0)
        source.SetRadius(5.0)

        # Create a mapper
        mapper = vtk.vtkPolyDataMapper()
        mapper.SetInputConnection(source.GetOutputPort())

        # Create an actor
        actor = vtk.vtkActor()
        actor.SetMapper(mapper)

        self.ren.AddActor(actor)

        self.ren.ResetCamera()

        self.widget.setLayout(self.vl)
        self.setCentralWidget(self.widget)

        self.show()
        self.iren.Initialize()
        self.iren.Start()


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

Rendering of Qt entities with QVTKRenderWindowInteractor.py is not supported and is likely to cause artifacts and instability. This is because neither VTK nor Qt know that the OpenGL context is shared. Very simple things might work (i.e. fully opaque pop-up menus) but anything more sophisticated than that might render incorrectly.

Proper sharing of a context between Qt and VTK is possible, and people who program in C++ can use QVTKRenderWindowAdapter for this. But this level of sophistication is not provided by QVTKRenderWindowInteractor.py.

Thanks for the quick reply.

Is it technically feasible in Python?

I see that QVTKRenderWindowAdapter is not included with the conda version of VTK. Is it because of performance issues with Python for such an implementation, or simply because nobody ever needed/requested it before?

I don’t know about the situation with VTK and conda, I don’t use conda.

There are no performance issues regarding QVTKRenderWindowAdapter and Python. It’s just that no-one has put in the necessary work to make VTK’s C++ Qt stuff accessible from the Python side. It isn’t something that would be trivial to do.