簡體   English   中英

從C ++實例化QML

[英]Instantiate QML From C++

我有2個類,MyApp和MyAppView。 MyApp類將包含其他類,並且實現將在這里。 (您可以將其稱為Manager類或System類)。 MyAppView類僅與main.qml交互,因為它將具有很多“ Q_PROPERTY”實體。 我認為您理解這一點。 我不希望MyApp擁有“ Q_PROPERTY”實體。

場景如下。

//------------------------------------
//---------------------------main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "myapp.h"
#include "myappview.h"

int main(int argc, char *argv[])
{
        QGuiApplication app(argc, argv);

        qmlRegisterType<MyAppView>("org.myappview", 1, 0, "MyAppView");

        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
        if (engine.rootObjects().isEmpty())
                return -1;

        MyApp myApp;

        return app.exec();
}



//------------------------------------
//---------------------------myappview.h
#include <QObject>

class MyAppView : QObject
{
        Q_OBJECT
        Q_PROPERTY(QString myString READ getMyString NOTIFY myStringChanged)

public:
        MyAppView();
        QString getMyString() { return m_myString; }
        void setMyString(QString newString)
        {
                m_myString = newString;
                emit myStringChanged;
        }

signals:
        void myStringChanged();

private:
        QString m_myString;
}



//------------------------------------
//---------------------------main.qml
import QtQuick 2.0
import QtQuick.Window 2.0

import org.myappview 1.0

Window {
        visible: true

        MyAppView {
                id: backend
        }

        Text {
                text: qsTr(backend.myString)
        }
}



//------------------------------------
//---------------------------myapp.h
#include <QObject>
#include "myappview.h"

class MyApp : QObject
{
        Q_OBJECT
public:
        MyApp();

private:
        MyAppView appView;
        void changeMyStringInAppView()
        {
                // This will automatically update main.qml
                appView.setMyString("This is new string");
        }
}

同樣,可以從MyApp到達現有QML實例,而不是從MyApp實例化QML。 因此,重點是從Manager類實例化或到達View類,以便我可以輕松控制它。 也許在某種程度上,我的邏輯是錯誤的。 請告訴我是否。 我對所有建議都同意。

代碼中的問題是MyAppMyAppView與QML中創建的MyAppView不同,因此,如果更新appView文本,它將不會反映在backend文本中,因此解決方案是使用以下方法將MyApp的對象公開給QML: setContextProperty()並將調用一個函數來建立在QML中創建的MyAppView (請記住僅創建一個MyApp但您將遇到相同的問題)

// myappview.h

#ifndef MYAPPVIEW_H
#define MYAPPVIEW_H

#include <QObject>

class MyAppView : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString myString READ getMyString NOTIFY myStringChanged)
public:
    explicit MyAppView(QObject *parent = nullptr) : QObject(parent)
    {}
    QString getMyString() const { return m_myString; }
    void setMyString(const QString & newString)
    {
        if(m_myString != newString){
            m_myString = newString;
            emit myStringChanged();
        }
    }
signals:
    void myStringChanged();
private:
    QString m_myString;
};

#endif // MYAPPVIEW_H

// myapp.h

#ifndef MYAPP_H
#define MYAPP_H

#include "myappview.h"
#include <QObject>

class MyApp : public QObject
{
    Q_OBJECT
public:
    explicit MyApp(QObject *parent = nullptr) : QObject(parent),
        appView(nullptr)
    {}
    Q_INVOKABLE void setAppView(MyAppView *value){
        appView = value;
    }
    void changeMyStringInAppView()
    {
       if(appView)
            appView->setMyString("This is new string");
    }
private:
    MyAppView *appView;
};

#endif // MYAPP_H

// main.cpp

#include "myapp.h"
#include "myappview.h"

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QTimer>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);
    qmlRegisterType<MyAppView>("org.myappview", 1, 0, "MyAppView");

    MyApp myapp;
    QTimer::singleShot(1000, &myapp, &MyApp::changeMyStringInAppView);

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("myapp", &myapp);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

// main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import org.myappview 1.0

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    MyAppView {
        id: backend
    }

    Text {
        text: qsTr(backend.myString)
    }
    Component.onCompleted: myapp.setAppView(backend)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM