pygfx / rendercanvas

One canvas API, multiple backends
https://rendercanvas.readthedocs.io
BSD 2-Clause "Simplified" License
8 stars 0 forks source link

Refactor initialization and re-order methods #11

Closed almarklein closed 2 weeks ago

almarklein commented 2 weeks ago

Tasks

Decisions

Some notes on decisions I came to. I feel like the text below makes little sense for anyone else, since its all a bit hard to explain and the problems are rather subtle. Nevertheless, I think its good to have this on record.

Init order

The initialization order is tricky. Taking qt as an example, the mro is:

All is good, except for one thing: I want BaseRenderCanvas to set the size and title (and maybe more in the future), because I don't want every subclass to have to bother with that. However, that must happen after the QRenderWidget did its initialization. I played with some ideas, and implemented one where the the backend class (QRenderWidget) must implement _rc_init instead of __init__. But this is too weird. Thought of metaclasses, but that's too dark. Using __new__ is also no help.

So I ended up with classic instantiation mechanics, and requiring backend canvas classes to call _final_canvas_init() to allow BaseRenderCanvas to apply the final configuration (setting size, title, transparency etc.) A little anoying, but its explicit. And if the class author forgets to call it, you simply don't get the custom title and size set.

Subwidget kwargs

Another tricky one, specific to the wrapper classes in qt and wx, was how to pass the right kwargs to the real canvas (._subwidget). I previously had tricks like a function that popped canvas kwargs form the kwargs dict. In the end the solution is quite simple: any kwargs that the toplevel widget wants, must be explicitly taken, the rest is passed to the subwidget:

class TopLevelClass(WrapperRenderCanvas, QWidget):
    def __init__(self, parent=None, **kwargs):
        super().__init__(parent)
        self._subwidget = QRenderWidget(self, **kwargs)
almarklein commented 2 weeks ago

Added some notes in the top comment.