[Development] Integrating QAction and the upcoming QML Action (was QAction-like API for QML)

André Somers andre at familiesomers.nl
Wed Dec 19 14:06:35 CET 2012


Op 19-12-2012 12:46, Stephen Kelly schreef:
> On Wednesday, December 19, 2012 08:57:31 André Somers wrote:
>
>> My preference is D, obviously. I think it makes a lot of sense to be
>> able to use actions in core, non-GUI layers of the application.
> Qt is primarily for creating Guis. I sympathise with the desire to use Action
> API in a 'core only' API without linking to QtGui or QtWidgets, but it's not
> what we should optimise for.
>
> Maybe it's something we can design for in Qt 6, but for now, focusing on
> solving problems in UI development should be reflected in our API and design
> choices. I'm thinking mostly about keeping QIcon, QKeySequence etc in the API.
>
I'm not too sure about your claim that Qt is primarily for creating 
Guis. That might have been the case when is was still "just" a widget 
library, but that has been a long, long time ago. Now, it offers many, 
many very useful tools for all layers of the application. But that 
doesn't mean you want to link against a GUI lib from a core layer in an 
application.

Last attempt on this topic though:

The nice thing about this (D) proposal is, that it can be done now 
(5.1), and it won't need new changes in actions for 6.0.

class QCoreAction: public QObject
{
     Q_PROPERTY (bool enabled READ enabled WRITE setEnabled NOTIFY 
enabledChanged)

     Q_SLOT trigger();
     Q_SIGNAL triggered();

     // and the property getters, setters and notifies above
}

though, it should probably keep the checked stuff as well:
class QCoreAction: public QObject
{
     Q_PROPERTY (bool enabled READ enabled WRITE setEnabled NOTIFY 
enabledChanged)
     Q_PROPERTY (bool checkable READ isCheckable WRITE setCheckable 
NOTIFY checkableChanged)
     Q_PROPERTY (bool checked READ isChecked WRITE setChecked NOTIFY 
checkedChanged)

public:
     QCoreAction(QObject* parent);

     Q_SLOT trigger();
     Q_SLOT toggle();
     Q_SIGNAL triggered(bool checked = false);
     Q_SIGNAL toggled(bool checked);
}

Very simple. Now, take the existing QAction, and add:

class QAction: public QObject
{
public:
    QAction(QCoreAction* coreAction, const QString& text, QObject* parent);
    QAction(QCoreAction* coreAction, const QIcon& icon, const QString& 
text, QObject* parent);

    QCoreAction* coreAction() const;
    void setCoreAction(QCoreAction* coreAction);
}

QAction would just use an internally constructed QCoreAction if none is 
set explicitly. QAction would basically simply connect to the 
QCoreAction's signals and slots. QAction can then both be used as-is, as 
well as with explicitly created QCoreActions.

QGuiAction can work in the same way.

I think a design like this has the following benefits:
* compatible with current Qt, no need to wait for Qt 6 for any of it. Qt 
5.1 would work.
* Makes the action concept usable in core application libraries that are 
restricted to linking against widget libs
* Keep QAction usable in the same way it is now
* Doesn't bind QML to QtWidgets or vise versa
* Legacy code can be used for binding with QML as well, because 
QCoreAction will be created implicitly by QAction without special work 
to be done for that bridge. All you need to do is share the coreAction 
instance.


André




More information about the Development mailing list