若该文为原创文章,转载请注明原文出处
此篇记录下Object类如何和QML交互的。工程模板还是以Hello_qml工程来测试。
一、创建Object类
1、创建C++类
在工程创建C++类,基础类一定要选择QObject,继承QObject,类名为MyObject.
2、创建属性
创建两个属性,以便QML访问,即在myobject.h中创建两个变量,一个int型,一个String型。
然后光标定位到变量上,按ALT+ENTER, 选择Generate Q_PROPERTY and Missing Members,如果没有选择项,可以直接自己编写。
确定后会生成以下内容,我们需要注意的是Q_PROPERTY属性,在此我C++类我们创建完成了。但现在访问是无法访问的,还需要注册类。
3、注册
注册有两种方式:
一、直接在main.cpp内创建obj,然后用setContextProperty注册,在此我们不测试
二、注册单例模式
注册单例模式是在项目中常用到的,那如何写一个单例呢?这里只是个例子,仅供参考。
一、修改myobject.h
二、修改myobject.cpp
三、在main.cpp注册单例
到此注册单例模式结束,但现在编译运行,在QML中还是无法访问,为什么呢?原本访问INT或STRING等变量是正常的,现在访问的是类,QML是不认识的,其实也很简单,只需要增加一个宏QML_ELEMENT,那么QML就可以识别了。
四、添加宏
在myobject.h添加宏
在.pro文件里添加下面的,MyObj就是我们要导入的模块。
通过上面步骤,我们就实现了QML和C++自定义类的交互。
在实际项目,其实注册方式我们也不是用上面的二种方式,而是使用qmlRegisterType来注册。
二、完整代码
1、main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "myobject.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
app.setOrganizationName("myApp");
QQmlApplicationEngine engine;
QQmlContext *context = engine.rootContext();
context->setContextProperty("SCREEN_WIDTH", 800);
// MyObject obj;
// context->setContextProperty("MyObject", &obj);
// context->setContextProperty("MyObject", MyObject::getInstance());
qmlRegisterType<MyObject>("MyObj", 1, 0, "MyObject");
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
2、myobject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H
#include <QObject>
#include <QtQml>
class MyObject : public QObject
{
Q_OBJECT
// QML_ELEMENT
Q_PROPERTY(int iValue READ iValue WRITE setIValue NOTIFY iValueChanged)
Q_PROPERTY(QString sString READ sString WRITE setSString NOTIFY sStringChanged)
public:
explicit MyObject(QObject *parent = nullptr);
static MyObject *getInstance();
int iValue() const;
void setIValue( int newIValue);
QString sString() const;
void setSString(const QString &newSString);
private:
int m_iValue;
QString m_sString;
signals:
void iValueChanged();
void sStringChanged();
};
#endif // MYOBJECT_H
3、myobject.cpp
#include "myobject.h"
MyObject::MyObject(QObject *parent) : QObject(parent)
{
}
MyObject *MyObject::getInstance()
{
static MyObject *obj = new MyObject();
return obj;
}
int MyObject::iValue() const
{
return m_iValue;
}
void MyObject::setIValue(int newIValue)
{
if(newIValue == m_iValue)
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();
}
4、结果
三、总结
1、自定义对象一定要继承QObject。
2、在实际项目,使用qmlRegisterType来注册。
3、值得注意的是Q_PROPERTY属性。
如有侵权,请及时联系博主删除,VX:18750903063