qt — у меня есть несколько файлов qml, которые отправляются через StackView. Как мне подключить их к переполнению стека

Мои проекты содержат 6 файлов qml: main.qml открывает новое окно ApplicationWindow и объявляет панель инструментов. Он также инициализирует StackView с помощью initalItem homescreen.qml. На главном экране у меня есть разные кнопки, которые открывают разные файлы qml через stack.push («URL»). Кроме main.qml все файлы начинаются с Item {}.
Я был в состоянии соединить сигналы из main.qml и home.qml. Но я не смог получить доступ к объектам, которые находятся глубже в стеке. Я не знаю, хочу ли я изменить свой код .cpp для доступа к другим объектам или мне следует изменить инициализацию StackView, чтобы все файлы загружались и были доступны в начале.
Вот код, разбитый до самых основ:

  • main.qml

    ApplicationWindow {
    Rectangle{
    id: homeButton
    objectName: "homeButton"signal qmlSignal(string msg)
    MouseArea {
    onClicked:  {stack.push({item:"qrc:/home.qml}); homeButton.qmlSignal("Hello")}
    }
    }
    StackView{
    initalItem: "qrc:/home.qml"}
    

    }

  • secondframe.qml // Случайный qml-файл, который появляется после главного экрана

    Item {
    Rectangle{
    id: test
    objectName: "test"signal qmlSignal(string msg)
    MouseArea {
    onClicked:  {stack.push({item:"qrc:/thirdframe.qml}); test.qmlSignal("Hello")}
    }
    }
    }
    
  • main.cpp

    QApplication app (argc, argv);
    QQmlEngine enigne;
    QQmlComponent component(&engine, QUrl(QStringLiteral("qrl:/main.qml")));
    QObject *object = componet.create();
    QQmlComponent newcomponent(&engine, QUrl(QStringLiteral("qrl:/secondframe.qml")));
    QObject *newobject = newcomponet.create();
    
    MyClass myClass
    QObject *home = object->findChild<QObject*>("homeButton");    // I'm able to connect to every Object in the main.qml or home.qml
    QObject::connect(home,SIGNAL(qmlSignal(Qstring)), &myClass, SLOT(cppSlot(QString)));
    QObject *test = newobject->findChild<QObject*>("test");       // Can't connect to the Objects in secondframe.qml
    QObject::connect(test,SIGNAL(qmlSignal(Qstring)), &myClass, SLOT(cppSlot(QString)));
    

3

Решение

Чтобы лучше подходить к дереву QML и извлекать объекты, которые могут быть, а могут и не быть, есть, предоставить API на основе C ++ для QML.

  1. Создайте класс на основе QObject, который имеет методы, которые QML должен вызывать как слоты или Q_INVOKABLE

    class MyAPI : public QObject
    {
    Q_OBJECT
    public slots:
    void cppSlot(const QString &text);
    };
    
  2. Создайте экземпляр этого и предоставьте его QML

    MyAPI myApi;
    QQmlEngine engine;
    engine.rootContext()->setContextProperty("_cppApi", &myApi);
    
  3. Используйте в QML, как если бы «_cppApi» был идентификатором объекта

    MouseArea {
    onClicked:  {stack.push({item:"qrc:/thirdframe.qml}); _cppApi.cppSlot("Hello")}
    }
    
3

Другие решения

После добавления qmls в стек объекты будут доступны. Поэтому, когда вы излучаете некоторый сигнал, когда объект будет в стеке, решение может выглядеть так:

MyClass myClass
QObject *home = object->findChild<QObject*>("homeButton");    // I'm able to connect to every Object in the main.qml or home.qml
QObject::connect(home,SIGNAL(qmlSignal(Qstring)), &myClass, SLOT(cppSlot(QString)));

connect( myClass, MyClass::emitWhenQMLIsAlreadyOnTheStack, this, [this](){
QObject *test = newobject->findChild<QObject*>("test");       // Now you should be able to connect
QObject::connect(test,SIGNAL(qmlSignal(Qstring)), &myClass, SLOT(cppSlot(QString));
});
-1

По вопросам рекламы [email protected]