本文记录下 QML 访问C++ 类的方式
QML 访问C++类 通过元对象系统实现,故C++类需要支持元对象特性,
将C++类 注册到QML 有两种方式:
main.cpp 中:
qmlRegisterType<CPlusPlusObject>("CPlusPlusObject",1, 0, "CPlusPlusObject");
QML文件:
import CPlusPlusObject 1.0
QQuickView view;
view.rootContext()->setContextProperty("customobject", &customobject);
QQmlEngine加载QML
QQmlEngine engine;
engine..rootContext()->setContextProperty("customobject", &customobject);
本文以从QObject 类派生CPlusPlusObject 对QML 访问常用的C++ 类中变量、结构等进行说明
class CPlusPlusObject : public QObject
{
Q_OBJECT
...
}
C++ 类中定义的函数在QML 中能够访问的前提 是函数用Q_INVOKABLE 标记
//.h
Q_INVOKABLE void customFun();
//.cpp
void CPlusPlusObject::customFun()
{
qDebug() << "customFun" ;
}
//.h
class CPlusPlusObject : public QObject
{
Q_OBJECT
Q_ENUMS(EM_CUSTOM_TYPE)
...
//枚举
enum EM_CUSTOM_TYPE
{
EM_CUSTOM_ONE =0,
EM_CUSTOM_TWO,
EM_CUSTOM_THREE,
EM_CUSTOM_NO
};
Q_INVOKABLE void customFun(EM_CUSTOM_TYPE type );
...
}
//.cpp
void CPlusPlusObject::customFun(EM_CUSTOM_TYPE type)
{
QString type_str;
switch (type)
{
case EM_CUSTOM_ONE:{type_str ="EM_CUSTOM_ONE" ;}break;
case EM_CUSTOM_TWO:{type_str ="EM_CUSTOM_TWO" ;}break;
case EM_CUSTOM_THREE:{type_str ="EM_CUSTOM_THREE" ;}break;
case EM_CUSTOM_NO:{type_str ="EM_CUSTOM_NO" ;}break;
default:{type_str ="Error" ;}
}
qDebug() << "customFun" << type_str;
}
变量以Q_PROPERTY 标记,Q_PROPERTY 格式如下:
以基本类型作为成员变量为例,在QML中对变量取值时调用 READ 后函数getiValue ,修改变量值调用WRITE后函数 setIvalue 并触发信号signal_iValueChange :
.h
Q_PROPERTY(int m_iValue READ getiValue WRITE setIvalue NOTIFY signal_iValueChange);
signals:
void signal_iValueChange(int ivalue);
private:
int m_iValue=0;
.cpp
connect(this,&CPlusPlusObject::signal_iValueChange,this,&CPlusPlusObject::slot_iValueChange);
void CPlusPlusObject::slot_iValueChange(int iValue)
{
qDebug() << "slot_iValueChange" << iValue;
}
int CPlusPlusObject::getiValue()
{
qDebug() << "getiValue" ;
return m_iValue;
}
void CPlusPlusObject::setIvalue(int iValue)
{
m_iValue = iValue;
qDebug() << "setIvalue" << iValue;
}
自定义数据结构通常用于业务数据封装,可以将struct 转成JSON字符串传递,本文给出 QVariantMap 的方式。
//.h
//自定义结构
struct Custom_Struct
{
int ivalue = 0 ;
QString strValue;
};
Q_INVOKABLE QVariantMap getCPlusPlusStruct();
private:
Custom_Struct m_structData;
//.cpp
CPlusPlusObject::CPlusPlusObject(QObject *parent) : QObject(parent)
{
m_structData.ivalue = 666;
m_structData.strValue="sdfhkdsfn";
}
QVariantMap CPlusPlusObject::getCPlusPlusStruct()
{
QVariantMap map;
map.clear();
map.insert("ivalue",m_structData.ivalue);
map.insert("strValue",m_structData.strValue);
return map;
}
可以将List 转成JSON字符串传递,本文给出 QVariantList的方式
//.h
Q_INVOKABLE QVariantList getCPlusPlusVector();
private:
QVector<int> m_vIntValue;
//.cpp
CPlusPlusObject::CPlusPlusObject(QObject *parent) : QObject(parent)
{
m_vIntValue.push_back(9);
m_vIntValue.push_back(8);
m_vIntValue.push_back(7);
}
QVariantList CPlusPlusObject::getCPlusPlusVector()
{
QVariantList list;
list.clear();
foreach(int var,m_vIntValue)
{
list.append(QVariant::fromValue(var));
}
return list;
}
对于信号 和槽 直接调用即可。
//.h
signals:
void signal_iValueChange(int ivalue);//含参
void signal_noPara();//不含参
public slots:
void slot_noPara();
void slot_iValueChange(int ivalue);
//.cpp connect(this,&CPlusPlusObject::signal_customPara,this,&CPlusPlusObject::slot_customPara);
connect(this,&CPlusPlusObject::signal_iValueChange,this,&CPlusPlusObject::slot_iValueChange);
void CPlusPlusObject::slot_noPara()
{
qDebug() << " slot_noPara ";
}
void CPlusPlusObject::slot_iValueChange(int iValue)
{
qDebug() << "slot_iValueChange" << iValue;
}
C++ 向QML 传递数据结构,可参见 Qt 文档Data Type Conversion Between QML and C++