Skip to content

Commit 6697ea5

Browse files
authored
Dont get winId in qt and wx with bitmap present-method (#60)
1 parent aed8cea commit 6697ea5

File tree

3 files changed

+27
-7
lines changed

3 files changed

+27
-7
lines changed

Diff for: docs/backends.rst

+11
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,17 @@ But the other way around, running a Qt canvas in e.g. the trio loop, works fine:
185185
trio.run(loop.run_async)
186186
187187
188+
There are known issue with Qt widgets that render directly to screen (i.e. widgets that obtain ``widget.winId()``),
189+
related to how they interact with other widgets and in docks.
190+
If you encounter such issues, consider using the bitmap present-method. That way, the rendering happens
191+
off-screen, and is than provided to Qt as an image. This is a safer approach, albeit lowers the performance (FPS)
192+
somewhat when the render area is large.
193+
194+
.. code-block:: py
195+
196+
widget = QRenderWidget(present_method="bitmap")
197+
198+
188199
Support for wx
189200
--------------
190201

Diff for: rendercanvas/qt.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,6 @@ def __init__(self, *args, present_method=None, **kwargs):
242242

243243
self._is_closed = False
244244

245-
self.setAttribute(WA_PaintOnScreen, self._present_to_screen)
246245
self.setAutoFillBackground(False)
247246
self.setAttribute(WA_DeleteOnClose, True)
248247
self.setAttribute(WA_InputMethodEnabled, True)
@@ -272,7 +271,8 @@ def _get_surface_ids(self):
272271
"display": int(get_alt_x11_display()),
273272
}
274273
else:
275-
raise RuntimeError(f"Cannot get Qt surface info on {sys.platform}.")
274+
logger.warning(f"Cannot get Qt surface info on {sys.platform}.")
275+
return None
276276

277277
# %% Qt methods
278278

@@ -304,12 +304,17 @@ def _rc_gui_poll(self):
304304

305305
def _rc_get_present_methods(self):
306306
global _show_image_method_warning
307-
if self._surface_ids is None:
307+
308+
if self._present_to_screen and self._surface_ids is None:
308309
self._surface_ids = self._get_surface_ids()
310+
if self._surface_ids is None:
311+
self._present_to_screen = False
309312

310313
methods = {}
311314
if self._present_to_screen:
312315
methods["screen"] = self._surface_ids
316+
# Now is a good time to set WA_PaintOnScreen. Note that it implies WA_NativeWindow.
317+
self.setAttribute(WA_PaintOnScreen, self._present_to_screen)
313318
else:
314319
if _show_image_method_warning:
315320
logger.warning(_show_image_method_warning)

Diff for: rendercanvas/wx.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,8 @@ def _get_surface_ids(self):
257257
"display": int(get_alt_x11_display()),
258258
}
259259
else:
260-
raise RuntimeError(f"Cannot get wx surface info on {sys.platform}.")
260+
logger.warning(f"Cannot get wx surface info on {sys.platform}.")
261+
return None
261262

262263
# %% Methods to implement RenderCanvas
263264

@@ -268,17 +269,20 @@ def _rc_gui_poll(self):
268269
loop.process_wx_events()
269270

270271
def _rc_get_present_methods(self):
271-
if self._surface_ids is None:
272+
global _show_image_method_warning
273+
274+
if self._present_to_screen and self._surface_ids is None:
272275
# On wx it can take a little while for the handle to be available,
273276
# causing GetHandle() to be initially 0, so getting a surface will fail.
274277
etime = time.perf_counter() + 1
275278
while self.GetHandle() == 0 and time.perf_counter() < etime:
276279
loop.process_wx_events()
277280
self._surface_ids = self._get_surface_ids()
278-
global _show_image_method_warning
281+
if self._surface_ids is None:
282+
self._present_to_screen = False
279283

280284
methods = {}
281-
if self._present_to_screen and self._surface_ids:
285+
if self._present_to_screen:
282286
methods["screen"] = self._surface_ids
283287
else:
284288
if _show_image_method_warning:

0 commit comments

Comments
 (0)