c++qmlsailfish-os

How to interact with the value of a Slider in Sailfish Silica / QML?


I seem to be totally lost in the declaration of forms in QML. I have a C++ object with properly set Q_PROPERTies, I have access to an object of that class in the QML, and I want to use sliders in the QML. How exactly do I make the value of the Slider update the information of the properties in the object, and vise-versa?


Solution

  • If it's anything like regular QML, then the following approaches will work.

    Context property

    Use an explicit Binding or use Slider's valueChanged signal:

    #include <QGuiApplication>
    #include <QtQml>
    
    class Object : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged)
    public:
        explicit Object(QObject *parent = 0) :
            QObject(parent),
            mValue(0)
        {
        }
    
        qreal value() const {
            return mValue;
        }
    
        void setValue(qreal value) {
            if (value != mValue) {
                mValue = value;
                emit valueChanged();
            }
        }
    signals:
        qreal valueChanged();
    private:
        qreal mValue;
    };
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        Object object;
    
        QQmlApplicationEngine engine;
        engine.rootContext()->setContextProperty("object", &object);
        engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
    
        return app.exec();
    }
    
    #include "main.moc"
    

    main.qml:

    import QtQuick 2.3
    import QtQuick.Controls 1.2
    
    ApplicationWindow {
        width: 400
        height: 400
        visible: true
    
        Binding {
            target: object
            property: "value"
            value: slider.value
        }
    
        Slider {
            id: slider
            // You can also react to the valueChanged signal of Slider:
            //onValueChanged: object.value = value
        }
    }
    

    Registered QML Type

    Use a simple binding:

    #include <QGuiApplication>
    #include <QtQml>
    
    class Object : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged)
    public:
        explicit Object(QObject *parent = 0) :
            QObject(parent),
            mValue(0)
        {
        }
    
        qreal value() const {
            return mValue;
        }
    
        void setValue(qreal value) {
            if (value != mValue) {
                mValue = value;
                emit valueChanged();
            }
        }
    signals:
        qreal valueChanged();
    private:
        qreal mValue;
    };
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        qmlRegisterType<Object>("Test", 1, 0, "Object");
    
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
    
        return app.exec();
    }
    
    #include "main.moc"
    

    main.qml:

    import QtQuick 2.3
    import QtQuick.Controls 1.2
    
    import Test 1.0
    
    ApplicationWindow {
        width: 400
        height: 400
        visible: true
    
        Object {
            id: object
            value: slider.value
            onValueChanged: print(value)
        }
    
        Slider {
            id: slider
        }
    }