# Issue with QVTKRenderWindowInteractor and PySide6 6.10.1 on MacOS

**URL:** https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225
**Category:** Development
**Tags:** python
**Created:** [January 12, 2026, 10:51pm UTC](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225 "2026-01-12T22:51:45Z")
**Posts on this page:** 17
**Page:** 1

<div class="post-metadata">

### Author: ![nchampag](https://discourse.vtk.org/user_avatar/discourse.vtk.org/nchampag/32/2763_2.png) [@nchampag](https://discourse.vtk.org/u/nchampag)
#### Post date: [January 12, 2026, 10:51pm UTC](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225/1 "2026-01-12T22:51:45Z")

</div>

The issue is code with QVTKRenderWindowInteractor on macOS that worked with  
VTK 9.4.2 and PySide6 6.9.3 fails to display anything after updating to PySide 6.10.1.  
No error message is displayed–it just hangs. Pressing ctrl-c during the run yields the following  
message:

```auto
Error calling Python override of QWidget::paintEvent(): Traceback (most recent call last):
File "/Users/nchampag/Documents/python/virtual/pyside6/lib/python3.13/site-packages/vtkmodules/qt/QVTKRenderWindowInteractor.py", line 465, in paintEvent
  self._Iren.Render()

```

Note that we tried using VTK 9.5.2, but it yielded the same hanging result.

FYI, the example works on Windows 10 with VTK 9.4.2 and PySide6 6.9.3/6.10.1.

Here is an example script:

```auto
#!/usr/bin/env python3

import sys

import vtkmodules.vtkInteractionStyle
import vtkmodules.vtkRenderingUI
import vtkmodules.vtkRenderingOpenGL2
from PySide6 import QtGui, QtWidgets
from vtkmodules.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from vtkmodules.vtkFiltersSources import vtkSphereSource
from vtkmodules.vtkRenderingCore import (
    vtkActor,
    vtkPolyDataMapper,
    vtkRenderer
)

class MainWindow(QtWidgets.QMainWindow):

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

        self.frame = QtWidgets.QFrame()

        self.vl = QtWidgets.QVBoxLayout()
        self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
        self.vl.addWidget(self.vtkWidget)

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

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

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

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

        self.ren.AddActor(actor)

        self.ren.ResetCamera()

        self.frame.setLayout(self.vl)
        self.setCentralWidget(self.frame)

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

if __name__ == " __main__":
    app = QtWidgets.QApplication(sys.argv)

    window = MainWindow()

    sys.exit(app.exec())

```

Any ideas?  
Thanks.

---

<div class="post-metadata">

### Author: ![dgobbi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dgobbi/32/18_2.png) [@dgobbi](https://discourse.vtk.org/u/dgobbi)
#### Post date: [January 13, 2026, 4:56pm UTC](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225/2 "2026-01-13T16:56:10Z")

</div>

This hang sounds similar to the one in issue [!19361](https://gitlab.kitware.com/vtk/vtk/-/issues/19361), which was fixed in VTK 9.3.1. So it’s not the exact same issue, but it is probably related.

The call to `Render()` on macOS will briefly trigger the macOS event loop for the render window, in order to ensure that macOS maps the window to the screen. In your case, it sounds as if running the event loop like this causes a deadlock with Qt6.10.

So I can guess at a possible solution. The `vtkCocoaRenderWindow::Render()` code can be changed so that it doesn’t trigger the macOS event loop if Qt is managing the window, since Qt will take care of mapping the window.

I can work on this, but probably not this week because I’m swamped…

---

<div class="post-metadata">

### Author: ![nchampag](https://discourse.vtk.org/user_avatar/discourse.vtk.org/nchampag/32/2763_2.png) [@nchampag](https://discourse.vtk.org/u/nchampag)
#### Post date: [January 13, 2026, 5:16pm UTC](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225/3 "2026-01-13T17:16:41Z")

</div>

Thanks for the reply. A quick solution isn’t needed at this time, but I can see macOS users wondering what’s happening as Qt6.10 is adopted by VTK/Qt/Python users.

---

<div class="post-metadata">

### Author: ![dgobbi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dgobbi/32/18_2.png) [@dgobbi](https://discourse.vtk.org/u/dgobbi)
#### Post date: [January 25, 2026, 10:02pm UTC](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225/4 "2026-01-25T22:02:33Z")

</div>

I looked into this in issue [#19915](https://gitlab.kitware.com/vtk/vtk/-/issues/19915) and it doesn’t seem related to VTK’s use of the macOS event loop.

It isn’t actually hanging `self._Iren.Render()`, the problem is that Qt is invoking `paintEvent()` over and over and this is causing `Render()` to be called repeatedly even though the window isn’t even showing on the screen. In other words, the issue seems to be an infinite loop in Qt, rather than a hang in VTK.

If you want to work on this issue yourself, start with the following code in QVTKRenderWindowInteractor.py. Try making it so that instead of calling Render() on every paintEvent(), it only calls Render() if certain conditions are met (I’m not sure myself what those conditions should be):

```auto
    def paintEvent(self, ev):
        self._Iren.Render()

```

---

<div class="post-metadata">

### Author: ![nchampag](https://discourse.vtk.org/user_avatar/discourse.vtk.org/nchampag/32/2763_2.png) [@nchampag](https://discourse.vtk.org/u/nchampag)
#### Post date: [January 27, 2026, 1:32am UTC](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225/5 "2026-01-27T01:32:39Z")

</div>

Thanks for the update and isolated code to start debugging.

---

<div class="post-metadata">

### Author: ![nchampag](https://discourse.vtk.org/user_avatar/discourse.vtk.org/nchampag/32/2763_2.png) [@nchampag](https://discourse.vtk.org/u/nchampag)
#### Post date: [January 29, 2026, 2:05am UTC](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225/6 "2026-01-29T02:05:27Z")

</div>

The [script](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225) above runs without a problem when using the following:

```auto
   def paintEvent(self, ev):
       if ev == QEvent.Type.Paint:
           self._Iren.Render()

```

---

<div class="post-metadata">

### Author: ![dgobbi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dgobbi/32/18_2.png) [@dgobbi](https://discourse.vtk.org/u/dgobbi)
#### Post date: [January 29, 2026, 4:48am UTC](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225/7 "2026-01-29T04:48:21Z")

</div>

It does seem to fix the hang (on macOS at least, I didn’t try Linux or Windows), but it’s incorrect code because it doesn’t call the `type()` method in order to get the event type. The correct code for checking the event type is:

```python
 def paintEvent(self, ev):
     if ev.type() == QEvent.Type.Paint:
         self._Iren.Render()

```

For your fix, `ev == QEvent.Type.Paint` always evaluates to `False`, so it’s really no different from simply removing `self._Iren.Render()`.

So I guess the question is, why does removing this `Render()` fix this macOS/PySide6.10 issue? And will removing the `Render()` have any side-effects, i.e. will it still render in all situations where it needs to?

---

<div class="post-metadata">

### Author: ![nchampag](https://discourse.vtk.org/user_avatar/discourse.vtk.org/nchampag/32/2763_2.png) [@nchampag](https://discourse.vtk.org/u/nchampag)
#### Post date: [January 29, 2026, 4:32pm UTC](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225/8 "2026-01-29T16:32:30Z")

</div>

Oops, you’re right. Back to the drawing board.

FWIW, example code for Mayavi hangs, now. I haven’t been able to find any posted issues about it, yet, on their Github.

---

<div class="post-metadata">

### Author: ![nchampag](https://discourse.vtk.org/user_avatar/discourse.vtk.org/nchampag/32/2763_2.png) [@nchampag](https://discourse.vtk.org/u/nchampag)
#### Post date: [January 29, 2026, 8:21pm UTC](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225/9 "2026-01-29T20:21:27Z")

</div>

FYI, it appears that the Mayavi hang is in the paintEvent function in Mayavi’s version of QVTKRenderWindowInteractor. So, the problem may be related.

---

<div class="post-metadata">

### Author: ![nchampag](https://discourse.vtk.org/user_avatar/discourse.vtk.org/nchampag/32/2763_2.png) [@nchampag](https://discourse.vtk.org/u/nchampag)
#### Post date: [February 18, 2026, 4:57pm UTC](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225/10 "2026-02-18T16:57:43Z")

</div>

A workaround seems to have been found that avoids the hang (so far). A flag (`__doPaintEvent()`) has been added to QVTKRenderWindowInteractor (see attached) that allows `paintEvent()` to be called only if the flag is `True`. It is initialized in the `init()` function and is set before calls to the `update()` function are made. Note that this approach works in QVTKRenderWindowInteractor provided by Mayavi, too.

[QVTKRenderWindowInteractor.py](https://discourse.vtk.org/uploads/short-url/kP7LCHnuhWHgonU3CzMUcWx0ZIK.py) (26.8 KB)

---

<div class="post-metadata">

### Author: ![dgobbi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dgobbi/32/18_2.png) [@dgobbi](https://discourse.vtk.org/u/dgobbi)
#### Post date: [February 22, 2026, 11:31pm UTC](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225/11 "2026-02-22T23:31:02Z")

</div>

Why is using this flag any better than simply removing `paintEvent()`?

---

<div class="post-metadata">

### Author: ![nchampag](https://discourse.vtk.org/user_avatar/discourse.vtk.org/nchampag/32/2763_2.png) [@nchampag](https://discourse.vtk.org/u/nchampag)
#### Post date: [February 23, 2026, 5:44pm UTC](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225/13 "2026-02-23T17:44:50Z")

</div>

Removing `paintEvent()` causes the initial display to be distorted in some way. For example, consider the attached cube example. Not calling `paintEvent()` results in a distortion  
in the initial (or updated) display (see attached figure) until the user interacts with the  
GUI.

[vtk\_cube.py](https://discourse.vtk.org/uploads/short-url/wKcEdkYx0OvLT1glmcN5swWcFZT.py) (2.6 KB)

 ![paintevent_removed](https://discourse.vtk.org/uploads/default/original/2X/9/9f9b3359477f2fae5b5de842eebc74e40b42f00f.jpeg)

---

<div class="post-metadata">

### Author: ![dgobbi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dgobbi/32/18_2.png) [@dgobbi](https://discourse.vtk.org/u/dgobbi)
#### Post date: [February 24, 2026, 5:43am UTC](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225/14 "2026-02-24T05:43:27Z")

</div>

I think I’ve found a fix that doesn’t require changes to `paintEvent()`: [!12956](https://gitlab.kitware.com/vtk/vtk/-/merge_requests/12956)

This seems to restore the behaviour to exactly what it was before.

---

<div class="post-metadata">

### Author: ![nchampag](https://discourse.vtk.org/user_avatar/discourse.vtk.org/nchampag/32/2763_2.png) [@nchampag](https://discourse.vtk.org/u/nchampag)
#### Post date: [February 24, 2026, 7:17pm UTC](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225/15 "2026-02-24T19:17:43Z")

</div>

This has worked for all the examples I have tried, so far. (FWIW, it doesn’t work for Mayavi–result is blank scene.)

Thanks for looking into this.

---

<div class="post-metadata">

### Author: ![cwantwm](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/c/90db22/32.png) [@cwantwm](https://discourse.vtk.org/u/cwantwm)
#### Post date: [July 12, 2026, 7:26pm UTC](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225/16 "2026-07-12T19:26:13Z")

</div>

I’m seeing the same “blank scene” regression from `!12956` that was just reported for Mayavi, in a third, independent codebase — [iMolpro](https://github.com/pjknowles/iMolpro), a Qt/VTK-based GUI. So this doesn’t seem specific to Mayavi’s own copy of the widget; it reproduces with a locally-vendored copy of `vtkmodules/qt/QVTKRenderWindowInteractor.py` patched with exactly the one-line change from `!12956`.

Setup: macOS arm64 (Apple Silicon), PySide6 6.11.0. With PySide6 6.9.x and the _unmodified_`QVTKRenderWindowInteractor.py` (`WA_PaintOnScreen` always set), everything renders correctly and immediately. With PySide6 6.11 and the unmodified widget, we get the hang described here. With PySide6 6.11 and `!12956`’s fix applied (skip `WA_PaintOnScreen` on `vtkCocoaRenderWindow`), the hang is gone, but the VTK widgets never render anything at all — not on initial show, and not after any user interaction (mouse clicks, resizes, tab switches). This matches what was reported for Mayavi exactly.

A couple of things I tried on top of `!12956`, in case they’re useful data points:

- Forcing an explicit `self._Iren.Render()` in a `showEvent` override, deferred via `QTimer.singleShot(0, ...)` to run after the native window is realized — no effect, still blank.
- Making `paintEngine()` conditional (returning a real Qt paint engine when `WA_PaintOnScreen` isn’t set, instead of always `None`) — this doesn’t help either, and I’d guess it’s actively wrong: `paintEvent()` still bypasses `QPainter` entirely and calls VTK’s own `Render()` directly, so giving Qt a “real” paint engine just means Qt starts managing a backing store that never gets painted into, while VTK’s actual OpenGL output has nowhere to be composited.

So my read is that removing `WA_PaintOnScreen` correctly stops Qt from getting into the paintEvent/Render feedback loop, but also removes the (apparently macOS-specific, and per Qt’s own docs technically unsupported: [“macOS always double buffers the screen, therefore, the Qt::WA\_PaintOnScreen attribute has no effect”](https://doc.qt.io/qt-6/macos-issues.html)) mechanism that was letting VTK’s raw OpenGL draw actually reach the screen at all under the old behavior. Without it, nothing tells Cocoa/Qt how to actually get VTK’s rendered frame on screen.

Happy to test any candidate patches against iMolpro if that’s useful — I have a real-world Qt/VTK app with tabbed VTK views, resizing, etc. that exercises this more than a minimal repro would.

---

<div class="post-metadata">

### Author: ![nchampag](https://discourse.vtk.org/user_avatar/discourse.vtk.org/nchampag/32/2763_2.png) [@nchampag](https://discourse.vtk.org/u/nchampag)
#### Post date: [July 12, 2026, 10:52pm UTC](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225/17 "2026-07-12T22:52:41Z")

</div>

FWIW, I have been using the version of QVTKRenderWindowInteractor listed [here](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225/10) without any problems. This version replaces any version used in a library (VTK, Mayavi, etc.).

---

<div class="post-metadata">

### Author: ![cwantwm](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/c/90db22/32.png) [@cwantwm](https://discourse.vtk.org/u/cwantwm)
#### Post date: [July 14, 2026, 3:06pm UTC](https://discourse.vtk.org/t/issue-with-qvtkrenderwindowinteractor-and-pyside6-6-10-1-on-macos/16225/18 "2026-07-14T15:06:45Z")

</div>

Following up with more data from our iMolpro, PySide6-based molecular viewer, hitting this family of issues on PySide6 6.11.1 / VTK 9.6.2 — cross-platform, not just macOS:

**Linux (X11):** No hang, but the VTK widget’s native window is not correctly embedded when the containing widget is constructed and only later added to a layout (via `layout.addWidget(...)`, as `QVTKRenderWindowInteractor` itself does internally through `winId()`/`SetWindowInfo()` at construction time). Symptom: the VTK content renders in a separate, floating top-level window instead of embedded in its intended tab, and appears to paint over sibling widgets (e.g. a containing tab bar’s contents/hit-area vanish). Passing the widget’s parent through to the base constructor at construction time (rather than reparenting afterward) did not fix this, so it isn’t simply a reparenting-order issue — something about how the native window created via `WA_PaintOnScreen` is embedded/composited appears to have changed under Qt 6.10+.

**Both platforms:** As a further experiment, forcing `vtkmodules.qt.QVTKRWIBase = "QOpenGLWidget"` (rather than the default `"QWidget"`) to sidestep the native-window path entirely produces an outright crash on both macOS and Linux — Qt’s own RHI backing-store compositor (`QBackingStoreDefaultCompositor`/`QRhiGles2`) fails to compile a legacy `#version 120` shader and segfaults, apparently because VTK’s own OpenGL context (compatibility profile) conflicts with the shared modern-profile context Qt 6’s RHI-based `QOpenGLWidget` compositing expects. So `QOpenGLWidget` isn’t a safe workaround as-is; it would likely need VTK’s context creation and/or the app’s default `QSurfaceFormat` to be made explicitly compatible with Qt’s RHI expectations.

For now we’ve reverted to pinning `pyside6 <6.10`, which continues to work correctly. Happy to help test candidate fixes against this codebase if useful.
