Discussion:
[Interest] promoting a QGuiApplication to a QApplication?
René J.V. Bertin
2018-07-11 09:28:48 UTC
Permalink
Hi,

I'm tinkering with using a Qt plugin that expects a QApplication in a QGuiApplication (specifically, a QML application using QGuiApplication).
I'm not doing anything that causes a straight crash (or haven't run into that one fatal instruction yet), but I do wonder:

is it in any way possible to promote a QGuiApplication instance to a QApplication? Somewhat unexpectedly, `dynamic_cast<QApplication*>(qApp)` behaves as `static_cast` or `const_cast` in this case (= it returns qApp). Or it returns a nullptr in

QGuiApplication app(argc, argv);
QApplication *gapp = dynamic_cast<QApplication*>(&app);

which is probably what you'd expect.

Still, with QApplication inheriting QGuiApplication one could think that the former does some initialisation the latter lacks and that it should be possible to perform those steps at a later stade. Is it?

Thanks,
R.
Konstantin Tokarev
2018-07-11 14:20:51 UTC
Permalink
Post by René J.V. Bertin
Hi,
I'm tinkering with using a Qt plugin that expects a QApplication in a QGuiApplication (specifically, a QML application using QGuiApplication).
is it in any way possible to promote a QGuiApplication instance to a QApplication? Somewhat unexpectedly, `dynamic_cast<QApplication*>(qApp)` behaves as `static_cast` or `const_cast` in this case (= it returns qApp). Or it returns a nullptr in
QGuiApplication app(argc, argv);
QApplication *gapp = dynamic_cast<QApplication*>(&app);
which is probably what you'd expect.
Still, with QApplication inheriting QGuiApplication one could think that the former does some initialisation the latter lacks and that it should be possible to perform those steps at a later stade. Is it?
If application object is created as QGuiApplication, you obviously cannot cast it to QApplication.

If you want to do something only when application object is created as QApplication (or its subclass), use qApp pointer
--
Regards,
Konstantin
René J.V. Bertin
2018-07-11 14:48:31 UTC
Permalink
On Wednesday July 11 2018 17:20:51 Konstantin Tokarev wrote:

Hi
Post by Konstantin Tokarev
If application object is created as QGuiApplication, you obviously cannot cast it to QApplication.
Maybe for casting, but
Post by Konstantin Tokarev
If you want to do something only when application object is created as QApplication (or its subclass), use qApp pointer
Well, that's not enough. qApp exists and isn't NULL in other Q*Applications because qApp is just a cast of QCoreApplication::instance().

A bit of context may help.

The plugin I'm tinkering with is KDE's qqc2-desktop-style, which aims to implement a QtQuickControls2 style that follows the user's current desktop (= widget) style. In its current implementation it does this by querying `qApp->style()` every time the style must be called upon. When you select that style in a basic QQC2 application (say, the gallery demo) it will crash horribly.

My tinkering is under review here: https://phabricator.kde.org/D14000 . Instead of using qApp->style() directly I use QStyleFactory to create a style instance when qApp->style() returns NULL, and cache it because qApp->setStyle(newStyle) would also crash.

This works fine, as long as the style doesn't do anything that requires a QApplication and will crash (or abort) otherwise.
The only guarantee I can think of is would be promoting a QGuiApplication instance to QApplication at runtime, in the plugin.

R.
Thiago Macieira
2018-07-11 15:01:25 UTC
Permalink
Post by René J.V. Bertin
The only guarantee I can think of is would be promoting a QGuiApplication
instance to QApplication at runtime, in the plugin.
There's no such C++ concept as "promote a class". What you're asking is not
possible.

If the QCoreApplication instance is an object of class QGuiApplication, it's
an object of class QGuiApplication and no other.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
J.V. Bertin
2018-07-11 17:30:37 UTC
Permalink
Post by Thiago Macieira
There's no such C++ concept as "promote a class". What you're asking is
not possible.
I think I got confused myself with dynamic_cast, but of course what I had
in mind was not modifying the instance itself, but create a new
QApplication instance from the original QGuiApplication instance. That's
what dynamic_cast also does when it doesn't simply return the original
pointer, no?


I have now seen from the code that this would probably be possible but not
without refactoring.

As I wrote in a private reply, maybe that one day it will be concluded
that QGuiApplication could be rolled into QApplication (because what's a
GUI application without widgets of some kind?). From an admittedly cursory
glance at qapplication.cpp it seems that a QApplication initialised with a
"noWidgets" flag would be largely identical to a QGuiApplication instance.
It also seems that the widget-related initialisations could be deferred
until they're actually needed in which case every QApplication would start
out as a QGuiApplication.

Maybe in Qt 7? :)

R.
Thiago Macieira
2018-07-11 18:05:08 UTC
Permalink
Post by J.V. Bertin
Post by Thiago Macieira
There's no such C++ concept as "promote a class". What you're asking is
not possible.
I think I got confused myself with dynamic_cast, but of course what I had
in mind was not modifying the instance itself, but create a new
QApplication instance from the original QGuiApplication instance. That's
what dynamic_cast also does when it doesn't simply return the original
pointer, no?
No.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Furkan Üzümcü
2018-07-11 18:27:25 UTC
Permalink
Post by J.V. Bertin
That's
what dynamic_cast also does when it doesn't simply return the original
pointer, no?
dynamic_cast<Type> returns nullptr when the class you are casting is cannot be cast down to Type. Casting does not create a new instance for you.

Regards,
Furkan ÜzÃŒmcÃŒ
Post by J.V. Bertin
Post by Thiago Macieira
There's no such C++ concept as "promote a class". What you're asking is
not possible.
I think I got confused myself with dynamic_cast, but of course what I had
in mind was not modifying the instance itself, but create a new
QApplication instance from the original QGuiApplication instance. That's
what dynamic_cast also does when it doesn't simply return the original
pointer, no?
I have now seen from the code that this would probably be possible but not
without refactoring.
As I wrote in a private reply, maybe that one day it will be concluded
that QGuiApplication could be rolled into QApplication (because what's a
GUI application without widgets of some kind?). From an admittedly cursory
glance at qapplication.cpp it seems that a QApplication initialised with a
"noWidgets" flag would be largely identical to a QGuiApplication instance.
It also seems that the widget-related initialisations could be deferred
until they're actually needed in which case every QApplication would start
out as a QGuiApplication.
Maybe in Qt 7? :)
R.
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
René J.V. Bertin
2018-07-11 20:12:19 UTC
Permalink
dynamic_cast<Type> returns nullptr when the class you are casting is cannot be cast down to Type. Casting does not create a new instance for you.
Yeah, I think I was misinformed or I misunderstood something at some point when someone first introduced the concept of dynamic_cast to me.

R.

Loading...