Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 38 additions & 3 deletions UM/Qt/Bindings/MainWindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from PyQt6.QtCore import pyqtProperty, Qt, QCoreApplication, pyqtSignal, pyqtSlot, QMetaObject, QRectF, QRect, QObject, \
QEvent
from PyQt6.QtGui import QColor
from PyQt6.QtQuick import QQuickWindow
from PyQt6.QtQuick import QQuickWindow, QQuickItem


from UM.Logger import Logger
Expand All @@ -18,6 +18,26 @@

from UM.View.GL.OpenGL import OpenGL


class _RenderRequestItem(QQuickItem):
"""Minimal scene graph item that drives Qt Quick render frames on demand.

In Qt 6.8+, QQuickWindow::update() alone may not trigger beforeRenderPassRecording
when no QML items are dirty. By participating in the scene graph with ItemHasContents
set, calling update() on this item properly marks the scene as dirty, guaranteeing
a render frame will be produced and beforeRenderPassRecording will fire.
"""

def __init__(self, parent = None):
super().__init__(parent)
# FIXME: As of time of writing, you can not reference flags by name in Qt6.
# Flag(8) is QQuickItem::ItemHasContents.
self.setFlag(QQuickItem.Flag(8))

def updatePaintNode(self, old_node, update_data):
return old_node # No visual content; exists only to drive the render cycle.


@signalemitter
class MainWindow(QQuickWindow):
"""QQuickWindow subclass that provides the main window."""
Expand Down Expand Up @@ -117,6 +137,9 @@ def __init__(self, parent = None):

self._allow_resize = True

self._render_request_item = None # type: Optional[_RenderRequestItem]
self.sceneGraphInitialized.connect(self._onSceneGraphInitialized)

# This event is triggered before hideEvent(self, event) event and might prevent window closing if
# does not pass the check, for example if USB printer is printing
# The implementation is in Cura.qml
Expand Down Expand Up @@ -304,13 +327,25 @@ def _render(self):
self._app.getRenderer().reRenderLast()
self.endExternalCommands()

def _onSceneGraphInitialized(self) -> None:
if self._render_request_item is None:
self._render_request_item = _RenderRequestItem(self.contentItem())
if self._full_render_required:
self._render_request_item.update()

def _onSceneChanged(self, object = None):
self._full_render_required = True
self.update()
if self._render_request_item is not None:
self._render_request_item.update()
else:
self.update() # Fallback before the scene graph is initialised.

def _onActiveViewChanged(self):
self._full_render_required = True
self.update()
if self._render_request_item is not None:
self._render_request_item.update()
else:
self.update() # Fallback before the scene graph is initialised.

@pyqtSlot()
def _onWindowGeometryChanged(self):
Expand Down
2 changes: 1 addition & 1 deletion UM/Qt/QtApplication.py
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ def createQmlSubWindow(self, qml_file_path: str, context_properties: Dict[str, "

# Keep a link to the window so that it is not garbage-collected, then register it for destruction
self._sub_windows.append(result)
result.visibleChanged.connect(self._onWindowVisibleChange)
result.visibleChanged.connect(self._onWindowVisibleChange, Qt.ConnectionType.QueuedConnection)

return result

Expand Down
Loading
Loading