[Qt-qml] Few beginner's questions about QML

Jerzy Chalupski jerzy.chalupski at gmail.com
Fri Nov 5 16:12:40 CET 2010


Hi,

I've been reading about and playing with Qt Quick for the last few
days and I have some questions:

1. I've always thought QML was supposed to be used strictly for
presentation layer of application, but in "declarative" examples and
demos usually whole logic is implemented in qml and javascript. Is
that an approach that you want to encourage (despite of breaking the
separation between presentation/business layers)?

2. Is there any official (i.e. the one that will be shipped with Qt
Quick in the future) set of standard primitives or widgets (absolutely
necessary for consistent look between apps)?

3. How one should deploy a QML application? In the examples I found
some apps that keep qml files in Qt Resource system and create
QDeclarativeView/Engine inside main.cpp and load QML from "qml:" URL.
Is that a way to go? The other approach would be providing QML files
in unchanged form in some subdirectory.

4. It seems that access to qrc and filesystem from QML is mutually
exclusive. What about QML which resides in qrc (to hide it from
users), but needs to read some graphics from filesystem (for example
theme resources)? Neither exposing qml files, nor keeping all data in
qrc doesn't sound good.

5. I'm wondering what's the best approach for integrating C++ engine
and QML UI. One way is to expose C++ QObject to QML by
QDeclarativeContext::setContextObjext() or
QDeclarativeContext::setContextProperty(). The other way is to get
root QML component from QDeclarativeView::rootObject() method (and
optionally find the QML object using QObject::findChild() if we need
some other object than root object).

Here's the list of things I'd like to be able to do:
    1. Send signal from QML to C++ (for example to change the state of
state machine when QML button is pressed).
    2. Have properties of QML components and C++ class synchronized
    3. Be able to call QML-side slots.

The third item on the list may seem redundant, i.e. the same can be
achieved by setting some property and have a QML state with "when"
condition linked to that property, but I think it's much clearer to
have qmlUi->startFluffyBunnyAnimation(); in C++ code than
engine->setFluffyBunnyAnimationStarted(true) (not to mention that the
startFluffyBunnyAnimation() is a slot and can be directly connected to
some signal).

The first two items can be done using first approach (exposing C++
QObject to QML), but it requires a lot of boilerplate code (14 lines
of code per property):
        class Engine : public QObject
        {
            Q_OBJECT
            Q_PROPERTY(int myStuff READ myStuff WRITE setMyStuff
NOTIFY myStuffChanged)

        public:
            explicit Engine(QObject *parent = 0) :
                QObject(parent),
                mMyStuff(0)
            {
            }

            int myStuff() const
            {
                return mMyStuff;
            }

            void setMyStuff(int newStuff)
            {
                if (newStuff != mMyStuff) {
                    mMyStuff = newStuff;
                    emit myStuffChanged();
                }
            }

        signals:
            void myStuffChanged();

        private:
            int mMyStuff;

        };

Besides, I still can't call QML functions. I found QtObject QML
component and it looks promising:

        // my main qml file
        import Qt 4.7

        Item {
            id: ui

            QtObject {
                // id and objectName are intentionally different:
                // from QML point of view, this object represents the engine
                // from C++ point of view, this object represents UI
                id: engine
                objectName: qmlUi

                // property
                property string myStuff

                signal foo()

                // slot from C++ perspective
                function bar() { console.log("Bar"); }
            }

            Text {
                id: someLabel
                text: engine.myStuff
            }

        }

The engine can be moved to separate file, which can be shared between
engine and UI teams. Is that correct approach or am I missing
something?



More information about the Qt-qml mailing list