1、第一种方法,通过 setContextProperty 直接将一个对象实例绑定到一个全局可访问的属性名上,这使得它在所有 QML 文件中都可以直接通过给定的属性名访问。
#include"myobject.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QScreen>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("MyObject", MyObject::getInstance());
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreationFailed,
&app,
[]() { QCoreApplication::exit(-1); },
Qt::QueuedConnection);
engine.loadFromModule("updatePublisher", "Main");
return app.exec();
}
在Main.qml中直接使用
import QtQuick
import QtQuick.Controls
Window {
id: window
width: MyObject.iValue //iValue为访问私有变量iValue的public函数
height: 480
visible: true
title: qsTr("Hello World")
}
2、通过 qmlRegisterSingletonType
,在 QML 系统中注册了一个 C++ 类型。这个类在 QML 中以模块的形式出现,可以像使用 QML 的其他类型那样使用它。(也可以用qmlRegisterSingletonInstance,这样就不需要改实例化函数的参数)
#ifndef MYOBJECT_H
#define MYOBJECT_H
#include <QObject>
#include <QtQml>
class MyObject : public QObject
{
Q_OBJECT
public:
explicit MyObject(QObject *parent = nullptr);
//修改单例函数,很重要
static MyObject *getInstance(QQmlEngine *engine, QJSEngine *scriptEngine);
int iValue() const;
void setIValue(int newIValue);
QString sString() const;
void setSString(const QString &newSString);
signals:
void iValueChanged();
void sStringChanged();
private:
int m_iValue = 200;
QString m_sString = " ";
Q_PROPERTY(int iValue READ iValue WRITE setIValue NOTIFY iValueChanged FINAL)
Q_PROPERTY(QString sString READ sString WRITE setSString NOTIFY sStringChanged FINAL)
};
#endif // MYOBJECT_H
#include "myobject.h"
MyObject::MyObject(QObject *parent)
: QObject{parent}
{}
MyObject *MyObject::getInstance(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
static MyObject *instance = new MyObject();
return instance;
}
int MyObject::iValue() const
{
return m_iValue;
}
void MyObject::setIValue(int newIValue)
{
if (m_iValue == newIValue)
return;
m_iValue = newIValue;
emit iValueChanged();
}
QString MyObject::sString() const
{
return m_sString;
}
void MyObject::setSString(const QString &newSString)
{
if (m_sString == newSString)
return;
m_sString = newSString;
emit sStringChanged();
}
#include"myobject.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QScreen>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterSingletonType<MyObject>("MyObt", 1, 0, "MyObject", MyObject::getInstance);
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreationFailed,
&app,
[]() { QCoreApplication::exit(-1); },
Qt::QueuedConnection);
engine.loadFromModule("updatePublisher", "Main");
return app.exec();
}
最后在qml文件中导入
import QtQuick
import QtQuick.Controls
import MyObt 1.0
Window {
id: window
width: MyObject.iValue
height: MyObject.iValue
visible: true
title: qsTr("Hello World")
}
3、整个过程没有使用到 QML_ELEMENT宏
和
qt6_add_qml_module(myapp
URI com.mycompany.qmlcomponents
VERSION 1.0
),这两者大部分应用于创建了一个 QML 模块,使其在多个项目或多个组件之间共享时,暂且没有遇到,遇到时再补充
4、qmlRegisterSingletonType与qmlRegisterType的区别
qmlRegisterSingletonType适用于访问自定义类中的成员函数/变量
qmlRegisterType可以支持你创建一个Component