0

I am struggling with this problem and I can find any solution. So I have this code for QML

Dial {
    id: volumeDial
    property int speedValue: volumeDial.value.toFixed(0)
    objectName: "speedDial"
    from: 0
    value: 42
    to: 100
    stepSize: 1
    Layout.alignment: Qt.AlignHCenter
    Layout.minimumWidth: 64
    Layout.minimumHeight: 64
    Layout.preferredWidth: 128
    Layout.preferredHeight: 128
    Layout.maximumWidth: 128
    Layout.maximumHeight: 128
    Layout.fillHeight: true
    Label {
        text: volumeDial.value.toFixed(0)
        horizontalAlignment: Text.AlignLeft
        fontSizeMode: Text.FixedSize
        color: "white"
        font.pixelSize: Qt.application.font.pixelSize * 3
        anchors.centerIn: parent
    }

My problem is that I want to store the value from the volumeDial.value in a int variable and after I moved the dial to update the int variable with the new volumeDial.value and so on. This is my .cpp code:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QSettings>
#include <QQuickStyle>
#include <QIcon>
#include <QDebug>
#include <QQmlProperty>
int main(int argc, char *argv[])
{
    QGuiApplication::setApplicationName("Automotive");
    QGuiApplication::setOrganizationName("QtProject");
    QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);

    QGuiApplication app(argc, argv);

    QIcon::setThemeName("automotive");

    QQmlApplicationEngine engine;
    engine.load(QUrl("qrc:/qml/automotive.qml"));
    if (engine.rootObjects().isEmpty())
        return -1;
    QObject *rootObject = engine.rootObjects().first();
    QObject *qmlObject = rootObject->findChild<QObject*>("speedDial");
  if(qmlObject)
  {
//      qDebug() << "Speed value:" << QQmlProperty::read(qmlObject, "speedValue").toInt();
       qDebug()<< qmlObject->property("value").toInt();
  }

    return app.exec();
}

Now I can get the initial value from the value.volumeDial but I want to get every value after I released the leftbutton click from the dial. In the Dial Signal Documentation there exists a function called moved() but I don't know how to use it and also I don't know if that function is the answer to my problem. I kindly ask you to show me with some code that can resolve my problem.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241

1 Answers1

1

In your current code you have a code that can cause you errors since you should not access QML elements from C++, but vice versa, inject C++ objects to QML, in addition it has the fault that you will only get the start value and you will not be notified of the changes.

In general if you want to monitor QML properties from C++ then you must create a QObject with a Q_PROPERTY of the same type of data you want to monitor, then export it with setContextProperty and make the connection in QML, then it is only a matter of monitoring the QProperty.

main.cpp

#include <QGuiApplication>
#include <QIcon>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include <QDebug>

class DialObserver: public QObject{
    Q_OBJECT
    Q_PROPERTY(int speed READ speed WRITE setSpeed NOTIFY speedChanged)
    int m_speed;
public:
    using QObject::QObject;
    int speed() const{
        return m_speed;
    }
public slots:
    void setSpeed(int speed){
        if (m_speed == speed)
            return;
        m_speed = speed;
        emit speedChanged(m_speed);
    }
signals:
    void speedChanged(int speed);
};

int main(int argc, char *argv[])
{
    QGuiApplication::setApplicationName("Automotive");
    QGuiApplication::setOrganizationName("QtProject");
    QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);

    QGuiApplication app(argc, argv);

    QIcon::setThemeName("automotive");

    DialObserver dial_observer;

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("dial_observer", &dial_observer);
    QObject::connect(&dial_observer, &DialObserver::speedChanged, [](int speed){
        qDebug() << speed;
    });
    engine.load(QUrl("qrc:/qml/automotive.qml"));
    if (engine.rootObjects().isEmpty())
        return -1;
    return app.exec();
}

#include "main.moc"

automotive.qml

// ...
Dial {
    id: volumeDial
    onValueChanged: dial_observer.speed = value.toFixed(0)
    from: 0
    value: 42
    to: 100
    // ...
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Thanks a lot, I wrote the code exactly like you did and I get the error undefined reference to 'vtable for DialObserver. I did some research and some people resolve this problem adding a destructor in the class but doesn't work for me do you have any solutions? Thank you in advance! – Mihai Bogdan Dec 22 '19 at 19:56
  • @MihaiBogdan Have you added `#include "main.moc"` to the end of main.cpp? If you have done so, delete the build folder and compile it back. What is the name of your .cpp? If your file is called `X.cpp` then you must change `#include "main.moc"` with `#include "X.moc"` – eyllanesc Dec 22 '19 at 19:58
  • @MihaiBogdan some feedback? – eyllanesc Dec 22 '19 at 21:44
  • I did what you said to do and still I get file not found. [https://imgur.com/a/NuRGhWx] I just want to thank you for all the help and time that you consume with me. I really appreciate. – Mihai Bogdan Dec 22 '19 at 21:55
  • @MihaiBogdan Press `Build->clean`, then `Build->Run qmake` and then recompile your project. – eyllanesc Dec 22 '19 at 21:57
  • https://imgur.com/a/NuRGhWx I did that and still the same problem.It's getting frustrated. – Mihai Bogdan Dec 22 '19 at 22:02
  • @MihaiBogdan Close Qt Creator and open it again, maybe it's a Qt Creator error. – eyllanesc Dec 22 '19 at 22:04
  • https://imgur.com/a/D7egszn . I closed the Qt Creator and I did again those steps with Clean and Run qmake anst still... – Mihai Bogdan Dec 22 '19 at 22:10
  • https://github.com/BogdanMhi/ErrorProject-eyllanesc.git Thanks! – Mihai Bogdan Dec 22 '19 at 22:36
  • @MihaiBogdan I created a PR: https://github.com/BogdanMhi/ErrorProject-eyllanesc/pull/1 – eyllanesc Dec 22 '19 at 22:47