[英]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類,以便我可以輕松控制它。 也許在某種程度上,我的邏輯是錯誤的。 請告訴我是否。 我對所有建議都同意。
代碼中的問題是MyApp
的MyAppView
與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.