P
P
Pavel K2016-03-19 12:58:39
Qt
Pavel K, 2016-03-19 12:58:39

How to make a bidirectional binding (communication) between Qt (C ++) and QML?

Greetings!
There is a class with a property, for example

class AppCore : public QObject
{
    Q_OBJECT
    Q_PROPERTY(int val1 READ val1 WRITE setVal1 NOTIFY val1Changed)
     ....

There is also a qml interface, for example
Window {
    visible: true
    property var appCore: null
    ....

In qml I pass the class object like this:
QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    AppCore * appCore = new AppCore(0);
    engine.rootObjects().at(0)->setProperty("appCore", qVariantFromValue(appCore));

Now the most interesting:
for example, there is a custom component that has some property, for example
WSlider.qml
Item {
    id: wSlider
    property double value: 100
    ....

In main.qml I include it:
WSlider {
    anchors.centerIn: parent
    value: appCore.val1 
  }

That is, I want that when changing in AppCore, the value in WSlider also changes, and vice versa, when the value in WSlider changes, it also changes in AppCore (the setVal1 slot worked
)
How to make it more beautiful, what was in both?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
Maxim Rybas, 2016-08-23
@MaxQwerty

You need to use not
engine.rootObjects().at(0)->setProperty("appCore", qVariantFromValue(appCore));
and forward this AppCore as a new component:

//это должно быть до строки 
//QQmlApplicationEngine engine;
qmlRegisterType<AppCore>("com.myown.project", 1, 0, "AppCore");

Then you declare it in a QML file
and you can use the AppCore element as usual. since it is a direct child of QObject, it will be invisible, like a normal QtObject. But now its AppCore property is available for you to bind:
AppCore
{
    id: appCoreId
    val1: 100500;
}

Now, we need to get an instance of this class back into C++. To do this, you can use the search by id:
//создавать придётся именно так:
QQmlEngine engine;
QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/main.qml")));
QObject *object = component.create();

//получаем созданный на стороне  QML истанс класса AppCore
AppCore* appCore = object->findChild<AppCore*>("appCoreId");

More details can be found here:
doc.qt.io/qt-5/qtqml-cppintegration-topic.html

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question