[Development] QAction-like API for QML

Stephen Kelly stephen.kelly at kdab.com
Tue Dec 11 15:07:13 CET 2012


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. 
We used flaps which could be dragged out from the left to contain actions:

 http://userbase.kde.org/File:Screenshot-20110214-162733.png

It is based on are actually QActions.

Here is the file which describes the actions for the notes application:

 http://quickgit.kde.org/?p=kdepim.git&a=blob&f=mobile%2Fnotes%2FNoteActions.qml

The NoteActions QML element was then used as any other QML element:

 SlideoutPanel {
   titleText: KDE.i18n( "Actions" )

   content : [
     NoteActions {
       id : noteActions
       // ...
     }
   ]
   // ...
 }   

For KMailMobile, the situation is similar:

 http://quickgit.kde.org/?p=kdepim.git&a=blob&f=mobile%2Fmail%2FKMailActions.qml

External objects (in C++ and in QML) can then manage the state of the actions. 
Eg, the reply action is only available when an email is selected etc. The 
'category' property is what we used to enable/show different actions based on 
context. If the application is in the home screen, then 'home actions' are 
available:

  ActionList {
    category : "home"
    name : "home_menu"
    text : KDE.i18n( "Home" )
    ActionListItem { name : "synchronize_all_items" }
    ActionListItem { name : "akonadi_empty_all_trash" }
    // ...
  }

If a mail folder is selected, then the actions for 'mark all as read', 'move 
all to trash' etc are available, and if category: "note_viewer", then we can 
reply, create events, etc. Note that multiple categories can be 'true' at 
once. The 'standard' category (the one representing 'quit' etc) is usually 
available as well as 'note_viewer' for example. 

See also 'function updateContextActionStates()' in:

 http://quickgit.kde.org/?p=kdepim.git&a=blob&f=mobile%2Fnotes%2Fnotes.qml

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.

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:

 http://quickgit.kde.org/?p=kdepim.git&a=blob&f=mobile%2Flib%2FApplicationGeneralActions.qml

The NoteActions.qml and KMailActions.qml have a ActionMenuContainer {} as 
their top-level.

 http://quickgit.kde.org/?p=kdepim.git&a=blob&f=mobile%2Flib%2FActionMenuContainer.qml

It uses the VisualItemModel to put items in a list. It can be nested 
arbitrarily (though we could only do 3 levels of nesting before running out of 
screen real-estate) as you see in the screenshot in my first link.



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'.

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.

Thanks,

-- 
Stephen Kelly <stephen.kelly at kdab.com> | Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
www.kdab.com || Germany +49-30-521325470 || Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-Independent Software Solutions
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.qt-project.org/pipermail/development/attachments/20121211/c3b9930e/attachment.sig>


More information about the Development mailing list