目錄
1 QML獲取C++的變量值
2 QML獲取C++創建的自定義對象
3 QML發送信號綁定C++端的槽
4 C++端發送信號綁定qml端槽
5 C++調用QML端函數
1 QML獲取C++的變量值
QQmlApplicationEngine engine;
全局對象
上下文屬性
QQmlApplicationEngine engine;
QQmlContext *context1 = engine.rootContext();
context1->setContextProperty("test",200);
在qml中可全局直接使用test?
2 QML獲取C++創建的自定義對象
光標放在成員變量m_iValue和m_sString后面 Alt + Enter 選擇第一個可自動生成函數
int m_iValue;
QString m_sString;
myobject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H#include <QObject>class MyObject : public QObject
{Q_OBJECT
public:explicit MyObject(QObject *parent = nullptr);int iValue() const;void setIValue(int newIValue);const QString &sString() const;void setSString(const QString &newSString);signals:void iValueChanged();void sStringChanged();private:int m_iValue;QString m_sString;Q_PROPERTY(int iValue READ iValue WRITE setIValue NOTIFY iValueChanged)Q_PROPERTY(QString sString READ sString WRITE setSString NOTIFY sStringChanged)
};#endif // MYOBJECT_H
myobject.c
#include "myobject.h"MyObject::MyObject(QObject *parent): QObject{parent}
{}int MyObject::iValue() const
{return m_iValue;
}void MyObject::setIValue(int newIValue)
{if (m_iValue == newIValue)return;m_iValue = newIValue;emit iValueChanged();
}const QString &MyObject::sString() const
{return m_sString;
}void MyObject::setSString(const QString &newSString)
{if (m_sString == newSString)return;m_sString = newSString;emit sStringChanged();
}
mian.c
注冊main.qml 中 import testObj 1.0使用
qmlRegisterType<MyObject>("testObj",1,0,"MyObject");
main.qml
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5
import testObj 1.0
Window {width: 640height: 480visible: truetitle: qsTr("Hello World")MyObject {iValue: 20sString: "test"}}
使用c++端的函數時需要在函數前面加上 Q_INVOKABLE
比如?Q_INVOKABLE void myFunction();
3 QML發送信號綁定C++端的槽
在mian.c先注冊?qmlRegisterType<MyObject>("testObj",1,0,"MyObject");
C++ 寫一個公有槽?
public slots:
? ? void qml_slot(QString str);
qml端通過按鈕發送信號
signal qml_signal(string str)
? ? Button {
? ? ? ? onClicked: {
? ? ? ? ? ? qml_signal("qml send signal test");
? ? ? ? }
? ? }
綁定信號和槽函數
Component.onCompleted: {
? ? ? ? qml_signal.connect(myobj.qml_slot)
? ? }
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5
import testObj 1.0
Window {id: windowwidth: 640height: 480visible: truetitle: qsTr("Hello World")MyObject {id: myobjiValue: 20sString: "test"}signal qml_signal(string str)Button {onClicked: {qml_signal("qml send signal test");}}//方法一
// Connections {
// target: window
// function onQml_signal(str){
// myobj.qml_slot(str)
// }
// }//方法二Component.onCompleted: {qml_signal.connect(myobj.qml_slot)}//方法三 mian.c 中engine load后//auto obj_list = engine.rootObjects();//auto window = list.first();//connect(window,SIGNAL(qml_signal(QString)),your function ptr,SLOT(qml_slot(QString)));}
4 C++端發送信號綁定qml端槽
myobject.h
信號 void signal_Cpp(QString str); 通過函數
Q_INVOKABLE void myFunction();發送
#ifndef MYOBJECT_H
#define MYOBJECT_H#include <QObject>class MyObject : public QObject
{Q_OBJECT
public:explicit MyObject(QObject *parent = nullptr);int iValue() const;void setIValue(int newIValue);const QString &sString() const;void setSString(const QString &newSString);Q_INVOKABLE void myFunction();static MyObject* getInstance();
public slots:void qml_slot(QString str);
signals:void iValueChanged();void sStringChanged();void signal_Cpp(QString str);
private:int m_iValue;QString m_sString;Q_PROPERTY(int iValue READ iValue WRITE setIValue NOTIFY iValueChanged)Q_PROPERTY(QString sString READ sString WRITE setSString NOTIFY sStringChanged)
};#endif // MYOBJECT_H
myobject.c
#include "myobject.h"
#include <QDebug>
MyObject::MyObject(QObject *parent): QObject{parent}
{}int MyObject::iValue() const
{return m_iValue;
}void MyObject::setIValue(int newIValue)
{if (m_iValue == newIValue)return;m_iValue = newIValue;emit iValueChanged();
}const QString &MyObject::sString() const
{return m_sString;
}void MyObject::setSString(const QString &newSString)
{if (m_sString == newSString)return;m_sString = newSString;emit sStringChanged();
}void MyObject::myFunction()
{emit signal_Cpp("signal_Cpp myFunction!");
}MyObject *MyObject::getInstance()
{static MyObject* obj = new MyObject();return obj;
}void MyObject::qml_slot(QString str)
{qDebug()<<"qml_slot"<<str;
}
mian.c
注冊單例類
qmlRegisterSingletonInstance("testObj",1,0,"MyObject",MyObject::getInstance());
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QtQml/qqml.h>
#include "myobject.h"int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endifQGuiApplication app(argc, argv);QQmlApplicationEngine engine;QQmlContext *context1 = engine.rootContext();context1->setContextProperty("test",200);//qmlRegisterType<MyObject>("testObj",1,0,"MyObject");qmlRegisterSingletonInstance("testObj",1,0,"MyObject",MyObject::getInstance());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
C++端發送信號
Button {
? ? ? ? onClicked: {
? ? ? ? ? ? //C++發送信號
? ? ? ? ? ? MyObject.myFunction()
? ? ? ? }
? ? }
連接QML端槽函數
Connections {
? ? ? ? target: MyObject
? ? ? ? function onSignal_Cpp(str) {
? ? ? ? ? ? //qml槽函數
? ? ? ? ? ? qmlSolt(str)
? ? ? ? }
? ? }
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5
import testObj 1.0
Window {id: windowwidth: 640height: 480visible: truetitle: qsTr("Hello World")// MyObject {
// id: myobj
// iValue: 20
// sString: "test"// }function qmlSolt(str) {console.log(str)}signal qml_signal(string str)Button {onClicked: {//C++發送信號MyObject.myFunction()}}Connections {target: MyObjectfunction onSignal_Cpp(str) {//qml槽函數qmlSolt(str)}}}
5 C++調用QML端函數
//main.c? load后獲取qml對象
? ? auto obj_list = engine.rootObjects();
? ? auto window = obj_list.first();
?//調用QML函數
? ? QMetaObject::invokeMethod(window,"qmlFunction",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Q_RETURN_ARG(QVariant,res),
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Q_ARG(QVariant,arg1),
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Q_ARG(QVariant,arg2)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? );
mian.qml
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5
import testObj 1.0
Window {id: windowwidth: 640height: 480visible: truetitle: qsTr("Hello World")function qmlFunction(arg1,arg2) {return arg1 + arg2;}}
mian.c
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QtQml/qqml.h>
#include "myobject.h"int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endifQGuiApplication app(argc, argv);QQmlApplicationEngine engine;QQmlContext *context1 = engine.rootContext();context1->setContextProperty("test",200);qmlRegisterType<MyObject>("testObj",1,0,"MyObject");//qmlRegisterSingletonInstance("testObj",1,0,"MyObject",MyObject::getInstance());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);//獲取qml對象auto obj_list = engine.rootObjects();auto window = obj_list.first();QVariant res;QVariant arg1 = "arg1";QVariant arg2 = "arg2";//調用QML函數QMetaObject::invokeMethod(window,"qmlFunction",Q_RETURN_ARG(QVariant,res),Q_ARG(QVariant,arg1),Q_ARG(QVariant,arg2));qDebug()<<res;return app.exec();
}