Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to connect signals from singleton object defined in C++ code to QML component?

Tags:

c++

qt

qt5

qml

My main objective is to receive signals from singleton objects while defining QML component in *.qml file.

Let's say I defined a singleton object in C++ code like this:

class MySingleton : public QObject
{
    Q_OBJECT

    Q_PROPERTY(QString value READ value WRITE setValue NOTIFY valueChanged)

    typedef QObject Base;
public:

    static MySingleton* instance();

    const QString& value() const;
    void setValue(const QString& value);

signals:
    void valueChanged();

private:
    MySingleton(QObject* parent = nullptr);
    QString m_value;
};

In MySingleton.cpp:

MySingleton* MySingleton::instance()
{
    static MySingleton* obj = new MySingleton();
    return obj;
}

const QString& MySingleton::value() const
{
    return m_value;
}

void MySingleton::setValue(const QString& value)
{
    if (value != m_value) {
        m_value = value;
        emit valueChanged();
    }
}

MySingleton::MySingleton(QObject* parent)
  : Base(parent),
    m_value("SomeInitialValue")
{
}

The singleton is successfully registered with QML engine:

QObject *getMySingleton(QQmlEngine *engine, QJSEngine *scriptEngine)
{
    Q_UNUSED(engine)
    Q_UNUSED(scriptEngine)

    return MySingleton::instance();
}

void qmlRegisterMySingleton()
{
    qmlRegisterSingletonType<MySingleton>("MySingleton", 1, 0, "MySingleton", &getMySingleton);
}

int main(int argc, const char** argv)
{
    ...
    qmlRegisterMySingleton();
    ...
}

Now, I try to use signals from the singleton. Somewhere in ".qml" file:

import QtQuick 2.1
import MySingleton 1.0

Rectangle {
    id: someRectangle
    property string singletonValue : MySingleton.value

    MySingleton.onValueChanged: {
       consol.log("Value changed")
    }
}

Using this syntax I receive the "Non-existent attached object" error for the line containing "MySingleton.onValueChanged:". Note that the assignment to the "singletonValue" property was successful.

I also tried to change a syntax to the following:

import QtQuick 2.1
import MySingleton 1.0

Rectangle {
    id: someRectangle
    property string singletonValue : MySingleton.value

    MySingleton {
        onValueChanged: {
            consol.log("Value changed")
        }
    }
}

The error message is "Element is not creatable", which is kind of expected.

My questions are:

  1. Is it possible to connect to a singleton signals when defining some QML component?
  2. If yes, what is the correct syntax?
  3. If not, what is the correct / accepted way to receive a notifications about core data change events (defined in some singleton object) while defining UI elements (widgets) in QML files?
like image 752
Alex Robenko Avatar asked Oct 11 '14 22:10

Alex Robenko


1 Answers

Try this:

Connections {
    target: MySingleton
    onValueChanged: {
        console.log("Value changed")
    }
}

Also

  • I guess your have a problem with deletion of singleton object.
  • You have typo in onValueChanged: - there is no consol object in QML
like image 71
folibis Avatar answered Oct 21 '22 05:10

folibis