Hello all,
(I’ve post this question also in qt forum: https://forum.qt.io/topic/116371/qwebengineview-and-vtk-widget-on-mac)
I’m building an application with a VTK widget (QVTKRenderWindowInteractor) to show 3D data and a QWebEngineView to show web pages. Under windows it works, although when I close it, it shows these messages:
2020-06-26 16:40:12.274 ( 27.459s) [ ]vtkWin32OpenGLRenderWin:217 ERR| vtkWin32OpenGLRenderWindow (000001185E1DA8B0): wglMakeCurrent failed in MakeCurrent(), error: The handle is invalid.
2020-06-26 16:40:12.296 ( 27.481s) [ ]vtkWin32OpenGLRenderWin:217 ERR| vtkWin32OpenGLRenderWindow (000001185E1DA8B0): wglMakeCurrent failed in MakeCurrent(), error: The handle is invalid.
2020-06-26 16:40:12.328 ( 27.513s) [ ]vtkWin32OpenGLRenderWin:90 ERR| vtkWin32OpenGLRenderWindow (000001185E1DA8B0): wglMakeCurrent failed in Clean(), error: 6
Under mac, the VTK widget appears black (the widget works if create_webengine_widget
is not called in the code below).
A code to reproduce this:
"""
Simple test of Python QVTKRenderWindowInterator,
requires either PySide2 or PyQt5.
"""
from vtkmodules.vtkFiltersSources import vtkConeSource
from vtkmodules.vtkRenderingCore import vtkActor, vtkPolyDataMapper, vtkRenderer, vtkTextActor
# load implementations for rendering and interaction factory classes
import vtkmodules.vtkRenderingOpenGL2
import vtkmodules.vtkInteractionStyle
import vtkmodules.vtkRenderingFreeType
import vtkmodules.qt
vtkmodules.qt.QVTKRWIBase = "QGLWidget"
from vtkmodules.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from vtkmodules.qt import PyQtImpl
if PyQtImpl is None:
# Autodetect the PyQt implementation to use
try:
import PyQt5
PyQtImpl = "PyQt5"
except ImportError:
import PySide2
PyQtImpl = "PySide2"
if PyQtImpl == "PyQt5":
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QSizePolicy
from PyQt5.QtWidgets import QFrame
from PyQt5.QtWidgets import QHBoxLayout
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWebEngineWidgets import QWebEngineSettings
from PyQt5.QtCore import Qt
from PyQt5.QtCore import QUrl
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtGui import QSurfaceFormat
from PyQt5.QtOpenGL import QGLFormat
elif PyQtImpl == "PySide2":
from PySide2.QtWidgets import QApplication
from PySide2.QtWidgets import QMainWindow
from PySide2.QtWidgets import QFrame
from PySide2.QtWidgets import QHBoxLayout
from PySide2.QtWebEngineWidgets import QWebEngineView
from PySide2.QtWebEngineWidgets import QWebEngineSettings
from PySide2.QtCore import Qt
from PySide2.QtCore import QUrl
from PySide2.QtCore import QCoreApplication
from PySide2.QtOpenGL import QGLFormat
else:
raise ImportError("Unknown PyQt implementation " + repr(PyQtImpl))
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.frame = QFrame()
self.frame_layout = QHBoxLayout()
self.frame.setLayout(self.frame_layout)
self.setCentralWidget(self.frame)
self.create_webengine_widget()
self.frame_layout.addWidget(self.view)
self.create_vtk_widget()
self.frame_layout.addWidget(self.vtk_widget)
self.show()
self.vtk_widget.Initialize()
self.vtk_widget.Start()
self.show_formats()
def create_vtk_widget(self):
print("Create vtk widget")
# create the widget
self.vtk_widget = QVTKRenderWindowInteractor(parent=self.frame)
ren = vtkRenderer()
ren.SetBackground(0, .1, .5)
self.vtk_widget.GetRenderWindow().AddRenderer(ren)
cone = vtkConeSource()
cone.SetResolution(8)
coneMapper = vtkPolyDataMapper()
coneMapper.SetInputConnection(cone.GetOutputPort())
coneActor = vtkActor()
coneActor.SetMapper(coneMapper)
ren.AddActor(coneActor)
def create_webengine_widget(self):
print("Create webengine widget")
self.view = QWebEngineView(self.frame)
self.view.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
self.view.settings().setAttribute(QWebEngineSettings.WebGLEnabled, False)
self.view.settings().setAttribute(QWebEngineSettings.Accelerated2dCanvasEnabled, False)
self.view.settings().setAttribute(QWebEngineSettings.LocalContentCanAccessRemoteUrls, True)
self.view.load(QUrl("http://www.google.com"))
def show_formats(self):
print("Widget format")
fmt = self.vtk_widget.format()
print(fmt.profile())
print("{}.{}".format(fmt.majorVersion(), fmt.minorVersion()))
print("-----------------")
print("QSurface format")
fmt = QSurfaceFormat.defaultFormat()
print(fmt.profile())
print(fmt.renderableType())
print("{}.{}".format(fmt.majorVersion(), fmt.minorVersion()))
print("-----------------")
print("QGLFormat")
fmt = QGLFormat.defaultFormat()
print(fmt.profile())
print("{}.{}".format(fmt.majorVersion(), fmt.minorVersion()))
print("-----------------")
if __name__ == "__main__":
print("Using " + PyQtImpl)
surfaceFormat = QGLFormat.defaultFormat()
surfaceFormat.setProfile(QGLFormat.CoreProfile)
surfaceFormat.setVersion(3, 3)
surfaceFormat.setSamples(4)
QGLFormat.setDefaultFormat(surfaceFormat)
QCoreApplication.setOrganizationName("QtExamples")
QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
QCoreApplication.setAttribute(Qt.AA_ShareOpenGLContexts)
# every QT app needs an app
app = QApplication(['QVTKRenderWindowInteractor'])
window = MainWindow()
# start event processing
app.exec_()
Under windows, the output of show_formats
is
Widget format
1
3.3
-----------------
QSurface format
0
0
2.0
-----------------
QGLFormat
1
3.3
-----------------
and under mac:
Widget format
1
4.1
-----------------
QSurface format
0
0
2.0
-----------------
QGLFormat
1
3.3
-----------------
In both OS, I’m using:
- Python 3.7 from conda
- pyqt5 and pyqtwebengine 5.15.0 from pip
- vtk 9.0.1 from pip
Does anybody has any idea where this could come from? Or how to test it further?
Thanks!
T.