KDAB Declarative Widgets : des composants Qt Quick appelant directement Qt Widgets
un outil facilitant le portage d'applications vers Qt Quick

Qt Quick et le langage QML permettent de décrire des interfaces, au lieu de la manière habituelle, plus impérative : on lie donc la valeur de certaines variables entre elles, de telle sorte que la mise à jour de l’une implique la mise à jour de l’autre, sans code supplémentaire requis. Avec Qt, cette API se nomme Qt Widgets. Jusqu’à présent, les interactions entre les deux univers sont relativement limitées, sauf pour intégrer des parties Qt Quick à des interfaces Qt Widgets.


Le module Declarative Widgets propose un autre pont entre ces deux mondes : la description d’interfaces à base de widgets. Ainsi, on peut utiliser tous les widgets habituels de Qt, mais dans la syntaxe Qt Quick, notamment avec les liaisons de propriétés. Dans l’exemple suivant, le titre d’un groupe de widgets est mis à jour dès que la propriété text d’un des deux champs d’édition de ligne change.

Code qml : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import QtWidgets 1.0
 
GroupBox {
    title: qsTr("New Contact: %1 %2").arg(firstName.text).arg(lastName.text)
 
    FormLayout {
        LineEdit {
            id: firstName
            FormLayout.label: qsTr("First Name")
        }
        LineEdit {
            id: lastName
            FormLayout.label: qsTr("Last Name")
        }
    }
}

La vraie puissance de ce module est qu’il est possible d’utiliser ainsi n’importe quel widget, notamment ceux développés au sein de chaque application Qt. Pour ce faire, les développeurs de KDAB ont implémenté quelques extensions de QWidget (cette classe ne propose pas toutes les propriétés par défaut de Qt Quick), ainsi qu’une fonction qmlRegisterExtendedType pour enregistrer un “objet d’extension” qui définit l’interface pour Qt Quick.

Code qt : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
qmlRegisterExtendedType<QWidget, DeclarativeWidgetExtension>(uri, 1, 0, "Widget");
 
class DeclarativeWidgetExtension : public DeclarativeObjectExtension
{
    Q_OBJECT
 
    // repeat property declarations, qmlRegisterExtendedType doesn't see the ones from base class
    Q_PROPERTY(QQmlListProperty data READ data DESIGNABLE false CONSTANT)
 
    Q_PROPERTY(int x READ x WRITE setX NOTIFY posChanged)
    Q_PROPERTY(int y READ y WRITE setY NOTIFY posChanged)
    Q_PROPERTY(int width READ width WRITE setWidth NOTIFY sizeChanged)
    Q_PROPERTY(int height READ height WRITE setHeight NOTIFY sizeChanged)
    Q_PROPERTY(QRect geometry READ geometry WRITE setGeometry NOTIFY geometryChanged)
    Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged)
 
    Q_CLASSINFO("DefaultProperty", "data")
}

Pour montrer la généricité de leur approche, ces développeurs ont fourni des exemples pour utiliser QQuickWidet et QWebEngineView… depuis Qt Quick. Bien évidemment, ces deux exemples ne sont pas très utiles en pratique (puisqu’on peut inclure une interface Qt Quick dans une autre interface Qt Quick et que Qt Web Engine dispose d’une API Qt Quick).

L’utilité principale de cette extension est d’aider au portage d’interfaces Qt Widgets vers Qt Quick.

Source : Declarative Widgets adding Qt Widgets support to QML.