[Interest] Embedding QWindow
Till Oliver Knoll
till.oliver.knoll at gmail.com
Tue Aug 5 10:27:18 CEST 2014
Am 04.08.2014 um 23:58 schrieb Ian Monroe <ian at monroe.nu>:
> On Mon, Aug 4, 2014 at 1:53 PM, rap <rap at dlc.fi> wrote:
>> From: Ian Monroe
>> On Mon, Aug 4, 2014 at 12:32 PM, rap <rap at dlc.fi> wrote:
>>>> Why do you want to use QWindow if you are using QWidget-based windows?
>>>>> QGLWidget seems like the correct solution.
>>>> Your question arises a question of the purpose and usefulness of QWindow
>>>> class regarding opengl if you can not easily create UI controls to go
>>>> it, at least in a SDI application. I'll check how things turn out with
>>>> and QWindow for child wnds.
>>> Sure you can create UI controls with QWindow, just use QML and Qt
>>> Quick Controls.You could do your own OpenGL stuff by subclassing
>>> QQuickItem. That's what QWindow is for. It's not meant to be poor
>>> replacement for QGLWidget.
>> OK, I'm not familiar with QML & QtQuick at all yet, only quite recently
>> started using Qt as an alternative for MS. If those support OpenGL core
>> profile 4+ then I'll have to take a look when I have the time, for now I
>> have to stick with Qt Creator.
> So the context is that QtWidgets (QWidget, QMainWindow etc) are the
> traditional but still fine-to-use UI component technology, and QML is
> the newer tech.
While "traditional" and "newer" sounds like the one is going to replace the other (which might or might not be the case), I'd say that QML is simply a "different" approach for designing GUIs. Simplified you could say it's all about "declarative" (QML) vs "imperative" (QWidgets).
Personally - for desktop applications - I still prefer "traditional widget hierarchies" with their very common parent-child paradigm (also in other GUI tool kits).
However if you're thinking about "full screen custom OpenGL GUIs" (well, "games" ;)) then mixing OpenGL with QtQuick (with its declarative "GUI language" QML) is definitively worth checking out!
There is a Qt example which does just that.
> The QML tech stack includes QWindow; QtWidgets doesn't
Technically QWindow is in the "base" QtGui library on which the QtWidget library is based (just like the corresponding QtQuick library, if I am not mistaken). But it is correct to say that QWindow was more meant to be a "low level window container" for QtQuick based applications. So it cannot really be directly incorporated into a QWidget hierarchy (like e.g. a top-level QDialog widget which could have another QMainWindow as parent).
But if I am not mistaken under the hood a QWindow is also used as base for e.g. a QMainWindow. It is just "the lowest common and most lightweight denominator" for interaction with the underlying "window system" (which could also simply be a framebuffer on embedded systems, if I understood this correctly).
> You can mix QtWidgets and QWindow/QML (with that
> createContainerWidget method or QQuickWidget),
That's exactly the magic keyword here, the static method of QWidget::createContainerWidget!
The only downside is you cannot (?) do that entirely within Qt Designer: you cannot e.g. simply drag'n'drop a QGLWidget into the Designer form and "promote" it to "MyOpenGLWidget".
So you have to insert another "Container" widget into the form (e.g. your QMainWidow) and add a QLayout to it, then in the c'tor of your QMainWindow based class create an instance of your OpenGL enabled QWindow, then create a "container widget" for it with the above method (which takes "ownership" over the QWindow) and add that newly created widget to your QLayout.
Works pretty well, with a little bit of hand-coding.
Off course the upcoming "QOpenGLWidget" (which replaces QGLWidget) would make that "boilerplate code" unnecessary again.
But for the time being - Qt 5.3 - and for new code QWindow/createWidgetContainer is the way to go, so I understand.
> but you shouldn't
> unless you have a reason to, and it sounds like you don't.
If you want to use QWidgets for *new* code and want to make use of the most recent "QOpenGL" classes (as opposed to the old "QGL" classes) then the "createWidgetContainer" way is the most sensible one to me. Also see below.
> If you want
> to use QtWidgets then you should probably just use QGLWidget.
There is a conversion method to convert a new QOpenGLContext (which was really designed to be used with QWindow and which you should be using now) to the old QGLContext, but that is really a "detour", since QGLContext is just a wrapper over the newer QOpenGLContext again. So when you create a QGLWidget with your converted QGLContext under the hood it will be converted back to a QOpenGLContext. Not a huge performance hit (if at all), but probably just a hint that you should be using QWindow based OpenGL rendering for /new/ code (and the upcoming QOpenGLWindow which I expect will then work with the new "QOpenGL" classes exclusively).
So for /existing/ code you can still use your QGLWidget, but progressively replace all other "QGL" classes with their "QOpenGL" counterparts.
For new code start using QOpenGL classes right away (including the new QWindow based OpenGL rendering).
More information about the Interest