在QML与C++的交互中,主要有两种方式:在C++中调用QML的方法和在QML中调用C++的方法。以下是具体的实现方法。
在C++中调用QML的方法
首先,我们需要在QML文件中定义一个函数,然后在C++代码中调用它。
示例
//QML main.qml文件
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle {
id: rect
width: 100
height: 100
color: "red"
function changeColor(newColor) {
rect.color = newColor;
}
}
}
//c++端 main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QDebug>
int main(int argc, char *argv[]) {
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
engine.load(url);
QObject *rootObject = engine.rootObjects().first();
QVariant returnedValue;
QVariant msg = "blue";
QMetaObject::invokeMethod(rootObject, "changeColor",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, msg));
return app.exec();
}
在QML中调用C++的方法
我们需要在C++类中定义一个方法,并使用Q_INVOKABLE宏标记它,然后在QML文件中调用该方法。
示例
Mclass.h
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>
class Myclass : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(int value READ getValue WRITE setValue NOTIFY valueChanged)
public:
Q_INVOKABLE void function1();
static Myclass* getInstance();
explicit Myclass(QObject *parent = nullptr);
const QString &name() const;
void setName(const QString &newName);
int getValue() const;
void setValue(int newValue);
public slots:
void setspeed(int setspeed);//槽函数
signals:
void nameChanged();
void valueChanged();
private:
QString m_name;
int value=0;
};
#endif // MYCLASS_H
Myclass.cpp
#include "myclass.h"
#include "QDebug"
void Myclass::function1()
{
qDebug()<<"qml端调用c++函数";
}
Myclass *Myclass::getInstance()
{
static Myclass* class1=new Myclass;
return class1;
}
Myclass::Myclass(QObject *parent) : QObject(parent)
{
}
const QString &Myclass::name() const
{
return m_name;
}
void Myclass::setName(const QString &newName)
{
if (m_name == newName)
return;
m_name = newName;
emit nameChanged();
}
int Myclass::getValue() const
{
return value;
}
void Myclass::setValue(int newValue)
{
if (value == newValue)
return;
value = newValue;
emit valueChanged();
}
void Myclass::setspeed(int setspeed)
{ this->value=setspeed;
qDebug()<<"qml槽函数运行"<<setspeed;
}
第一步就完成了,那如何通过注册好以后在qml中如何调用C++的函数?
第二步:就是将调用函数前要加入Q_INVOKABLE 宏,这样这个函数才能够在qml中调用
最后一步,通过在main.cpp中注册某个类,通过这个注册好的版本号引入对应要调用的qml文件中,然后直接通过 类.函数 调用对应的函数
main.cpp中注册类
#include <QQmlApplicationEngine>
#include<QQmlContext>
#include <QLoggingCategory>
#include "myclass.h"
#include <QIcon>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);//初始化 Qt 应用程序。参数 argc 和 argv 用于命令行参数。
// app.setWindowIcon(QIcon("icon/icon.png"));
QQmlApplicationEngine engine;//创建一个 QML 应用程序引擎实例,负责加载 QML 代码
QLoggingCategory::setFilterRules(QStringLiteral("qt.qml.binding.removal.info=true"));
//注册属性到 qml 不常用
// Myclass myclass;
// engine.rootContext()->setContextProperty("myclass", &myclass);
//在qml加载之前注册c++类
//qmlRegisterType注册C++类到QML
//arg1:import时模块名 在qml中使用import QmlTestObject 1.0引入文件,1.0是主版本和次版本号
//arg2:主版本号
//arg3:次版本号
//arg4:QML类型名
//注册完成后去qml文件去使用
qmlRegisterType<Myclass>("Myclass",1,0,"Myclass");
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();
main.qml调用
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.0
import Myclass 1.0
Window {
id:rootwindow
visible: true
width: 640;
height: 480
title: qsTr("Hello qt")
property int myspeed:myclass.value
signal setspeed(int set_spped)
signal setqmlspeed(int set_qmlspped)
Myclass{
id:myclass
value: slider.value
}
Button {
text: "调用c++函数"
onClicked: {
myclass.function1()
// myclass.value=100;
// console.log( myclass.value)//value 没有改变
}
}
}