Задать вопрос
PavelK
@PavelK

Как сделать двунаправленный биндинг(связь) между Qt (C++) и QML?

Приветствую!
Есть класс cо свойством, например
class AppCore : public QObject
{
    Q_OBJECT
    Q_PROPERTY(int val1 READ val1 WRITE setVal1 NOTIFY val1Changed)
     ....


Так же есть qml интерфейс, например
Window {
    visible: true
    property var appCore: null
    ....

В qml передаю объект класса так:
QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

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


Теперь самое интересное:
например есть кастомный компонент, у которого есть некоторое свойство, например
WSlider.qml
Item {
    id: wSlider
    property double value: 100
    ....


В main.qml его подключаю:
WSlider {
    anchors.centerIn: parent
    value: appCore.val1 
  }


Тоесть хочу, что бы при изменении в AppCore менялось значение и в WSlider, и наоборот, при изменении значения в WSlider оно менялось и в AppCore (срабатывал слот setVal1 )
Нор баотает либо в одну либо в другую сторону.
Как по-красивше сделать, что было в обе?
  • Вопрос задан
  • 764 просмотра
Подписаться 2 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 1
MaxQwerty
@MaxQwerty
Linux, C++, Pyton, ML
Вам нужно использовать не
engine.rootObjects().at(0)->setProperty("appCore", qVariantFromValue(appCore));
а пробросить этот AppCore как новый компонент:
//это должно быть до строки 
//QQmlApplicationEngine engine;
qmlRegisterType<AppCore>("com.myown.project", 1, 0, "AppCore");

Потом в QML-файле объявляете
import com.myown.project 1.0
и можете использовать элемент AppCore как обычный. так как он прямой потомок от QObject, то он будет невидимым, подобно обычному QtObject. Но теперь вам доступно для биндинга его свойство AppCore:
AppCore
{
    id: appCoreId
    val1: 100500;
}

Теперь, нужно достать инстанс этого класса обратно в С++. Для этого можно использовать поиск по id:
//создавать придётся именно так:
QQmlEngine engine;
QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/main.qml")));
QObject *object = component.create();

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


Более подробно можно почитать тут:
doc.qt.io/qt-5/qtqml-cppintegration-topic.html
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы