概述
QML,V8,CEF中都涉及到C++和JavaScript之间的调用。
QML
QML调用C++
定义C++类,类需要继承
QObject
,在类中添加Q_OBJECT
宏;信号函数、public
槽函数可以在QML中访问;public
普通成员函数,需要用Q_INVOKABLE
标记才能在QML中访问;成员属性,需要定义setter
和getter
函数,并通过Q_PROPERTY
注册,才能在QML中访问。
#include <QObject>
// 需要派生自QObject
class CppObject : public QObject
{
Q_OBJECT
// 属性:使用Q_PROPERTY注册属性,使之可以在QML中访问
Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChanged)
public:
explicit CppObject(QObject *parent = nullptr);
// 函数:通过Q_INVOKABLE宏标记的public函数可以在QML中访问
Q_INVOKABLE void testFun();
// 给类属性添加访问方法--myName
void setName(const QString &name);
QString getName() const;
signals:
// 信号:可以直接在QML中访问信号
void cppSignalA();//一个无参信号
void cppSignalB(const QString &str,int value); // 一个带参数信号
public slots:
// 槽函数:可以直接在QML中访问public槽函数
void cppSlotA();//一个无参槽函数
void cppSlotB(const QString &str,int value); // 一个带参数槽函数
private:
// 类的属性
QString myName;
};
注册C++类到QML
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "CppObject.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
// QML方式:qmlRegisterType注册C++类型至QML
// 参数:qmlRegisterType<C++类型名> (import时模块名 主版本号 次版本号 QML中的类型名)
qmlRegisterType<CppObject>("MyCppObject", 1, 0, "CppObject");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
在QML中使用C++类。QML中所有的成员函数都是槽函数,所有的属性都有
getter
和setter
成员。
import QtQuick 2.9
import QtQuick.Window 2.9
// 引入我们注册的模块
import MyCppObject 1.0
Window {
id: root
visible: true
width: 500
height: 300
// 以QML的方式使用C++类
CppObject{
id: cpp_obj
}
// 关联信号与信号处理函数的方式同QML中的类型
Component.onCompleted: {
// Qml对象的信号关联到Cpp的槽函数
root.onQmlSignalA.connect(cpp_obj.cppSlotA)
// 1.修改属性会触发set函数,获取值会触发get函数
cpp_obj.name = "gongjianbo"
// 2.调用Q_INVOKABLE宏标记的函数
cpp_obj.testFun()
// 3.发射C++信号
cpp_obj.cppSignalA()
}
}
C++调用QML
QQuickItem
对应Item