[Development] QAction-like API for QML

Alan Alpert 416365416c at gmail.com
Tue Dec 11 18:48:22 CET 2012

On Tue, Dec 11, 2012 at 6:07 AM, Stephen Kelly <stephen.kelly at kdab.com> wrote:
> On Monday, December 10, 2012 19:39:36 Alan Alpert wrote:
>> Here's a hypothetical example of how it could work
>> in practice.
>> MenuControl {
>>     //Default property is property list<Action> actions
>>     ActionGroup {
>>         id: fileActions
>>         text: "File"
>>         collapsible: true
>>         Action { text: "New..."; onTriggered: launchNewFileDialog() }
>>         Action { text: "Load..."; onTriggered: launchLoadFileDialog() }
>>         Action { text: "Save..."; onTriggered: launchSaveFileDialog() }
>>         ActionGroup {
>>             text: "Recent"
>>             collapsible: true
>>             QtObjectRepeater {
>>                 model: recentFiles
>>                 delegate: Action { text: fileName; onTriggered:
>> openFile(fileName) }
>>             }
>>         }
>>     }
>>     Action { id: quitAction; text: "Quit"; onTriggered: Qt.quit(); }
>> }
>> ToolBarControl {
>>     //Default property is  property list<Action> actions
>>     actions: [fileActions, quitAction]
>> }
> For comparison, you could look at what we did with QML1 based kdepim-mobile.

Great, thanks! It's always good to see how this can is handled in real
applications. I just hope that we can make it 10x easier to write
something like this in QML2 ;) .

> ...
> The actions are represented as strings. The mapping from string to action is
> via KActionCollection:
>  http://api.kde.org/4.x-api/kdelibs-
> apidocs/kdeui/html/classKActionCollection.html
> This is necessary because an Action element with an id is not available in a
> global scope, but a string can be used to access the actual action via an
> exported object (with setContextProperty). You can't really expect people to
> make sure that particular elements are accessible through their QML element
> id. That might work for 'small/toy' applications or apps, but not for large
> ones.

Perhaps then we just need to make item access easier, like with the
proposed QML singleton API? What if you had your ActionLists as QML
singletons, or on a QML singleton, would that make it easier? You'd be
able to access it anywhere in your application with something like

If you had globally accessible ids and ActionGroups with an enabled
property, would you still need the categories? Would bindings on the
enabled state suffice? something like enabled: { ["mainView",
"composeView", "subComposeView"].contains(ApplicationState.currentView);}

> Another point is that some actions are 'standard', and may have a common
> handling among many applications. In NoteActions.qml you'll see
> ApplicationGeneralActions {} used. That defines the quit and configure
> actions, the about dialog etc:

If there's a common Actions API, this is something that the platform
components sets can provide. Including their common
icon/string/secondaryText and such.

> ...
> So, in summary, I think your proposal needs more work. I think the use-cases
> of hybrid applications, the use-cases of multiple applications with some
> common stuff, and the use-cases of large applications need to be satisfied by
> any new 'action API'.

There is always a conflict between "done" and "released". If we want
to get an Action API into 5.1 so that QtQuick Controls can use it,
then we need to start small. This means that all these usecases should
be considered future tasks and not in the initial implementation. That
doesn't mean we can't think about it and discuss it, we'd like the
design to be future proof, but we also can't let those discussions
prevent getting something out for the key usecase of QtQuick Controls

> We also need to find out whether we can come up with something which QtWidgets
> users can migrate to (the QWidget* in the QAction API is quite niche, and not
> necessarily ideal API anyway). Possibly even investigating whether QAction can
> be implemented in terms of a new QGuiAction (?) API should be done. This can't
> be QML-only. There needs to be C++ backing too.

Why can't this be QML-only? For the set of controls exposed in
C++-only we have a C++-only Action API. When we add a set of controls
exposed in QML-only we can have a QML-only Action API. We don't
currently have a C++ UI something which QtWidget users can migrate to,
we'd need to consider that first before trying to make this new API
fit in with whatever that would be.

I agree there should be a migration path for existing QAction users,
and that we should support hybrid applications. But there are other
ways to support those use cases than adding a C++ API for the new
Actions. My initial thought is something like a QActionBridge which
can take a QAction or a QML Action to start with and then generates
the other on the fly. It's not pretty, but it's a lot easier than
abstracting out a QGuiAction and still allows you to get a reference
to the other type if you need the interoperability.

Alan Alpert

More information about the Development mailing list