[Development] QAction-like API for QML
andre at familiesomers.nl
Thu Dec 20 11:43:11 CET 2012
Op 20-12-2012 11:10, Bache-Wiig Jens schreef:
>>> I find the idea of adding a new QCoreAction base class that is shared between QML Action and QAction and only carries a small subset of properties an unnecessary layer of abstraction. The idea of QAction is to have the convenience of icons, text and shortcuts predefined for you in a shared location. If you remove most of those properties, you anyway have to redefine the shortcuts and icon every time you use them and quite frankly I see no added benefit of this core action class that I cannot cover by simply having a shared signal that my MenuItem connects to.
>> Well, I disagree with that view of what an action represents. To me, the
>> core of an action really is bundling a bit of state with a trigger for
>> something to happen (I try to avoid the word 'action' here) in a
>> convenient API. That piece of state includes at minimum if that action
>> is available right now, and can also contain a value ('checked' is the
>> value that QAction can currently carry, so basically a boolean). That by
>> itself is already a very useful thing to have, as it provides a very
>> nice and clean way to expose functions on an API, especially for code in
>> a core layer of the application.
> Action has clear semantics in Qt. It is a GUI concept to describe properties that belong in a specific implementation of a UI. What you are proposing should not be called CoreAction as it has nothing todo with QAction. You are proposing a new concept to Qt. I still find it redundant since it is trivial to implement yourself, but if your backend needs a signal that can be disabled I would suggest that we introduce it as a different class called QTrigger and keep it outside of this discussion.
> If you have doubts that Action is a GUI concept, take a look at the properties:
> autoRepeat, checkable, checked, enabled, font, icon, iconText, iconVisibleInMenu, menuRole, priority, shortcut, shortcutContext, softKeyRole, statusTip, text, toolTip, visible, whatsThis. How many of those belong in a backend? How many can you reuse in both mobile and desktop UI's?
Right. So, because of the way QAction is implemented (tightly bound to
QtWidgets), you conclude that it is a GUI concept. Why not conclude it
is a QtWidgets concept then, and from that, conclude that is has no role
in QML? That's just as silly.
Of course none of the GUI properties it carries belong in a backend. Did
you even look at the quick draft I posted? Did it contain *any* of those
properties? Call it what you want. If you call it QTrigger instead of
QCoreAction, fine. I don't care. The point says the same: it can and
should (IMnsHO) the core can common base of QAction and a QML equivalent.
>> You claim that you'd have to "redefine" the shortcuts and other GUI
>> related properties every time you use the (core) action. Why so? Your
>> GUI layer can simply get these core actions and re-expose them once,
>> right? At the moment, you frequently see methods that are responsible
>> for creating all the actions in the application. You'd have the same,
>> only instead of having to manage multiple connections to keep track of
>> state in the core and the action that represents that, you set a
>> coreAction on the action and have that part taken care of. Then, you set
>> the QAction you created on your toolbar, your menu and whatever else you
> So you redeclare your Actions in your fronted and somehow associate them with CoreAction?
> QGuiAction openAction(Core::openCoreAction):
> openAction.setToolTip, setEtc…
> Again, I gain nothing from this apart from having to declare all my actions twice. Though if the concept is worth implementing we can alway add a setTrigger function to QGuiAction in the future.
No, you do *not* declare all your actions twice. Why would you think so?
You are just _able_ to split the declaration of the core stuff of the
action (trigger, if you prefer) in another place, application layer or
library than the GUI representation of it. If you don't want that, you
don't have to.
If you are talking about it being different for QML and QtWidgets, and
having to re-declare this stuff for both gui types: that is true. The
GUI is likely to be different as well, including having different icons,
so what's the point?
Or are you just complaining about the legacy case, where a user might
have existing, already completely defined QActions, and the user wants
to expose these to QML, and then has to re-declare the GUI-parts of it?
There, you might have a point. Could be easy to fix for the most part in
the implementation though, I think. For instance, one could use a tactic
where if a QAction is declared not using a QCoreAction/QTrigger, QAction
just sets as many of the other properties as possible on the
QCoreAction/QTrigger (perhaps using a set of dynamic properties), and
QGuiAction just sees what it can use from these. That could make most
data available transparently (thus easing using legacy), without binding
the class to the GUI lib.
>> The benefit is in the way that you bundle the relevant bit of state, a
>> handle to an action and a value into one convenient abstraction. Instead
>> of having to expose and connect to these separately to keep your GUI
>> consistent with application state, you only need to reference a single
>> object. And that single object can be used both in the widget world as
>> well as in the QML world. At the same time, if you like.
>>> What I would propose is that we keep the QAction exactly as it is and make it possible to use it from QML as well as introduce a new slightly simplified QML Action component as previously suggested. The only drawback to this approach is that actions you declare in QML won't be immediately usable from C++, but I don't see this as a big issue. You will either keep everything in QML or have your business logic including your QActions defined in in C++.
>> As mentioned by others, this would mean that any C++ core that you write
>> would *have* to pull in QtWidgets in order to be able to use actions.
>> Even if you only have a QML gui. Not very attractive, if you ask me.
> No it does not. QtWidgets is in a separate library. We will put the new C++ class in QtGui and expose it to QtQuick. This would then be just as available to widgets as it is in QtQuick. But I am not a sure how much effort we should use to make it usable in widgets. I would like it to be optimised for QtQuick. QAction already works great for widgets. Making QQuick also support QAction seems more important to existing users.
Ah, so you want to end up with a one-way compatibility again. QML can
use stuff from the Qt/C++/Widgets world, but the other way around is not
important. Good to know that the claim that "QtWidgets is and remains a
first-class citizen" is being upheld so nicely.
More information about the Development