马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
QML与C++交互
使用全局对象
main.cpp
- #include <QGuiApplication>
- #include <QQmlApplicationEngine>
- #include <QQmlContext>
- #include <QScreen>
- #include <QRect>
- int main(int argc, char *argv[])
- {
- QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
- QGuiApplication app(argc, argv);
- QQmlApplicationEngine engine;
- //全局对象,上下文对象
- QQmlContext* context = engine.rootContext();
- QScreen*screen = QGuiApplication::primaryScreen();
- QRect rect = screen->availableGeometry();
- context->setProperty("SCREEN_WIDTH",rect.width()/2 ); // 定义一个全局的属性可以给qml去使用
- 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.12
- Window {
- visible: true
- width: SCREEN_WIDTH //从main.cpp中拿到这个变量的值
- height: screen.desktopAvailableHeight/2 //screen可以获取到屏幕的相关大小。
- title: qsTr("Hello World")
- }
复制代码 使用qmlRegisterType模板类
myobject.cpp
- #include "myobject.h"
- MyObject::MyObject(QObject *parent) : QObject(parent)
- {
- }
- MyObject *MyObject::getInst()
- {
- static MyObject* obj = new MyObject;
- return obj;
- }
- int MyObject::iValue() const
- {
- return m_iValue;
- }
- void MyObject::setIValue(int iValue)
- {
- m_iValue = iValue;
- }
- QString MyObject::sString() const
- {
- return m_sString;
- }
- void MyObject::setSString(const QString &sString)
- {
- m_sString = sString;
- }
复制代码 myobject.h
- #ifndef MYOBJECT_H
- #define MYOBJECT_H
- #include <QObject>
- #include <QtQml>
- class MyObject : public QObject
- {
- Q_OBJECT
- // QML_ELEMENT //声明为QML元素,低版本5.12 qt没有
- public:
- explicit MyObject(QObject *parent = nullptr);
- static MyObject* getInst();
- void fun();
- int iValue() const;
- void setIValue(int iValue);
- Q_PROPERTY(int iValue MEMBER m_iValue NOTIFY iValueChanged) //这个和下面那个都可以,经测试,使用MEMBER可以触发信号,下面的不行。
- // Q_PROPERTY(int iValue READ iValue WRITE setIValue NOTIFY iValueChanged) //QT宏,iValue是声明的名称,可以通过名称获取,并且创建读取和设置的函数,在新加一个值改变的信号。
- Q_PROPERTY(QString qstr READ sString() WRITE setSString NOTIFY sStringChanged) //QT宏,iValue是声明的名称,可以通过名称获取,并且创建读取和设置的函数,在新加一个值改变的信号。
- QString sString() const;
- void setSString(const QString &sString);
- private:
- int m_iValue; //光标定位在属性上,键盘按下Alt+Enter 选择第一个
- QString m_sString;
- signals:
- void iValueChanged();
- void sStringChanged();
- };
- #endif // MYOBJECT_H
复制代码 main.cpp
- #include <QGuiApplication>
- #include <QQmlApplicationEngine>
- #include <QQmlContext>
- #include <QScreen>
- #include <QRect>
- #include <QtDebug>
- #include "myobject.h"
- int main(int argc, char *argv[])
- {
- QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
- QGuiApplication app(argc, argv);
- QQmlApplicationEngine engine;
- //全局对象,上下文对象
- QQmlContext* context = engine.rootContext();
- QScreen*screen = QGuiApplication::primaryScreen();
- QRect rect = screen->availableGeometry();
- qDebug()<<rect.width()/2;
- context->setProperty("SCREEN_WIDTH",500 ); // 定义一个全局的属性可以给qml去使用
- // context->setProperty("MyObject",MyObject::getInst()); //使用单例模式来创建一个对象。
- qmlRegisterType<MyObject>("MyObj",1,0,"MyObject"); //myobj qml要导入的名称,主版本,次版本,使用对象
- 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.12
- import MyObj 1.0
- Window {
- visible: true
- // width: SCREEN_WIDTH //从main.cpp中拿到这个变量的值,12版本似乎拿不到。
- width: screen.desktopAvailableWidth/2
- height: screen.desktopAvailableHeight/2 //screen可以获取到屏幕的相关大小。
- title: qsTr("Hello World")
- property int val: myobj.iValue
- MyObject{ //C++中的对象。
- id:myobj
- iValue: 1
- qstr: "12"
- Component.onCompleted: {
- console.log("ivalue = ",myobj.iValue," qstr = ",myobj.qstr)
- }
- onIValueChanged: { //这个信号来自与QT中的MODIFY信号,本人测试,在cpp中使用MEMBER方式可以绑定,其他不行
- console.log("iValue changed = ",iValue)
- }
- }
- Button{
- onClicked: {
- myobj.iValue =100
- console.log("clicked myobj.iValue = ",myobj.iValue)
- }
- }
- onValChanged: {
- console.log("val = ",val)
- }
- }
复制代码 QML端直接访问C++的函数
需要在C++类的函数使用Q_INVOKABLE宏,就可以完成直接访问,见下图。
C++端直接调用qml函数
QML发送信号C++接收
方式一:在QML端绑定信号
main.qml
- import QtQuick 2.12
- import QtQuick.Window 2.12
- import QtQuick.Controls 2.12
- import MyObj 1.0
- Window {
- id:window
- visible: true
- width:600
- height: 400
- title: qsTr("QML与C++交互")
- signal qmlSig(int i,string s)
- MyObject{ //C++中的对象。
- id:myobj
- iValue: 1
- m_sString: "m_sString_test"
- }
- Button{
- onClicked: {
- console.log("click")
- qmlSig(10,"张三") //点击发送信号,让C++端去接受他。
- }
- }
- //方式一:
- Connections{
- target: window
- onQmlSig:{
- myobj.cppSlot(i,s) //直接调用槽函数。
- }
- }
- // 方式二
- Component.onCompleted: {
- qmlSig.connect(myobj.cppSlot)
- }
- }
复制代码 方式二:在C++端绑定信号
main.cpp
- #include <QGuiApplication>
- #include <QQmlApplicationEngine>
- #include <QQmlContext>
- #include <QScreen>
- #include <QRect>
- #include <QtDebug>
- #include <QObject>
- #include "myobject.h"
- int main(int argc, char *argv[])
- {
- QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
- QGuiApplication app(argc, argv);
- qDebug()<<QGuiApplication::platformName();
- QQmlApplicationEngine engine;
- //全局对象,上下文对象
- QQmlContext* context = engine.rootContext();
- QScreen*screen = QGuiApplication::primaryScreen();
- QRect rect = screen->availableGeometry();
- qDebug()<<rect.width()/2;
- context->setProperty("SCREEN_WIDTH",500 ); // 定义一个全局的属性可以给qml去使用
- // context->setProperty("MyObject",MyObject::getInst()); //使用单例模式来创建一个对象。
- qmlRegisterType<MyObject>("MyObj",1,0,"MyObject"); //myobj qml要导入的名称,主版本,次版本,使用对象
- 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);
- //engine加载完成之后
- auto list = engine.rootObjects(); //返回的是main.qml QML文件的所有对象。
- //第一个元素的windows
- QObject* window = list.first();
- QObject* btn = list.first()->findChild<QObject*>("mybtn");
- qDebug()<< window <<"|"<< window->objectName();
- qDebug()<< btn <<"|"<< btn->objectName();
- // 方式三
- QObject::connect(window,SIGNAL(qmlSig(int,QString) ),MyObject::getInst(),SLOT(cppSlot(int,QString)) );
- // MyObject* w = MyObject::getInst();
- // QObject::connect(window, &QQuickWindowQmlImpl_QML_0::qmlSig, //这里无法用qt5的信号槽连接。
- // w, &MyObject::cppSlot);
- return app.exec();
- }
复制代码 C++端发送信号绑定qml函数
方式一
main.cpp
- #include <QGuiApplication>
- #include <QQmlApplicationEngine>
- #include <QQmlContext>
- #include <QScreen>
- #include <QRect>
- #include <QtDebug>
- #include <QObject>
- #include "myobject.h"
- int main(int argc, char *argv[])
- {
- QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
- QGuiApplication app(argc, argv);
- qDebug()<<QGuiApplication::platformName();
- QQmlApplicationEngine engine;
- //全局对象,上下文对象
- QQmlContext* context = engine.rootContext();
- QScreen*screen = QGuiApplication::primaryScreen();
- QRect rect = screen->availableGeometry();
- qDebug()<<rect.width()/2;
- context->setProperty("SCREEN_WIDTH",500 ); // 定义一个全局的属性可以给qml去使用
- // context->setProperty("MyObject",MyObject::getInst()); //使用单例模式来创建一个对象。
- qmlRegisterType<MyObject>("MyObj",1,0,"MyObject"); //myobj qml要导入的名称,主版本,次版本,使用对象
- 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);
- //engine加载完成之后
- auto list = engine.rootObjects(); //返回的是main.qml QML文件的所有对象。
- //第一个元素的windows
- QObject* window = list.first();
- QObject* btn = list.first()->findChild<QObject*>("mybtn");
- qDebug()<< window <<"|"<< window->objectName();
- qDebug()<< btn <<"|"<< btn->objectName();
- // 方式三
- QObject::connect(window,SIGNAL(qmlSig(int,QString) ),MyObject::getInst(),SLOT(cppSlot(int,QString)) );
- // MyObject* w = MyObject::getInst();
- // QObject::connect(window, &QQuickWindowQmlImpl_QML_0::qmlSig, //这里无法用qt5的信号槽连接。
- // w, &MyObject::cppSlot);
- return app.exec();
- }
复制代码 main.qml
- import QtQuick 2.12
- import QtQuick.Window 2.12
- import QtQuick.Controls 2.12
- import MyObj 1.0
- Window {
- id:window
- visible: true
- width:600
- height: 400
- objectName: "mywindow"
- title: qsTr("QML与C++交互")
- signal qmlSig(int i,string s)
- MyObject{ //C++中的对象。
- id:myobj
- iValue: 1
- m_sString: "m_sString_test"
- }
- Button{
- objectName: "mybtn"
- onClicked: {
- console.log("click")
- // myobj.cppSig(100,"test");
- myobj.fun()
- }
- }
- Connections{
- target: myobj
- onCppSig:{
- console.log(i,s);
- }
- // function onCppSig(i,s){
- // qmlSlot(i,s)
- // }
- }
- }
复制代码 myobject.cpp
- #include "myobject.h"
- MyObject::MyObject(QObject *parent) : QObject(parent)
- {
- }
- MyObject *MyObject::getInst()
- {
- static MyObject* obj = new MyObject;
- return obj;
- }
- void MyObject::fun()
- {
- qDebug()<<__FUNCTION__;
- emit cppSig(1,"C++");
- }
- int MyObject::iValue() const
- {
- return m_iValue;
- }
- void MyObject::setIValue(int iValue)
- {
- m_iValue = iValue;
- }
- QString MyObject::sString() const
- {
- return m_sString;
- }
- void MyObject::setSString(const QString &sString)
- {
- m_sString = sString;
- }
- void MyObject::cppSlot(int i, QString s)
- {
- qDebug()<<__FUNCTION__ <<i<< s;
- }
复制代码 myobject.h
- #ifndef MYOBJECT_H
- #define MYOBJECT_H
- #include <QObject>
- #include <QtQml>
- class MyObject : public QObject
- {
- Q_OBJECT
- // QML_ELEMENT //声明为QML元素,低版本5.12 qt没有
- public:
- explicit MyObject(QObject *parent = nullptr);
- static MyObject* getInst();
- Q_INVOKABLE void fun(); //Q_INVOKABLE宏可以让qml直接访问函数。
- int iValue() const;
- void setIValue(int iValue);
- Q_PROPERTY(int iValue MEMBER m_iValue NOTIFY iValueChanged) //这个和下面那个都可以,经测试,使用MEMBER可以触发信号,下面的不行。
- Q_PROPERTY(QString m_sString MEMBER m_sString NOTIFY sStringChanged) //QT宏,iValue是声明的名称,可以通过名称获取,并且创建读取和设置的函数,在新加一个值改变的信号。
- QString sString() const;
- void setSString(const QString &sString);
- private:
- int m_iValue; //光标定位在属性上,键盘按下Alt+Enter 选择第一个
- QString m_sString;
- public slots:
- void cppSlot(int i,QString s);
- signals:
- void iValueChanged();
- void sStringChanged();
- void cppSig(int i,QString s);
- };
- #endif // MYOBJECT_H
复制代码 方式二
main.cpp
- #include <QGuiApplication>
- #include <QQmlApplicationEngine>
- #include <QQmlContext>
- #include <QScreen>
- #include <QRect>
- #include <QtDebug>
- #include <QObject>
- #include "myobject.h"
- int main(int argc, char *argv[])
- {
- QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
- QGuiApplication app(argc, argv);
- qDebug()<<QGuiApplication::platformName();
- QQmlApplicationEngine engine;
- qmlRegisterType<MyObject>("MyObj",1,0,"MyObject"); //通过模板创建
- //通过单例创建
- // qmlRegisterSingletoInstance("MyObj",1,0,"MyObject",MyObject::getInst() );//没有这个方法qt15引入。
- 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);
- //engine加载完成之后
- auto list = engine.rootObjects(); //返回的是main.qml QML文件的所有对象。
- //第一个元素的windows
- QObject* window = list.first();
- QObject* btn = list.first()->findChild<QObject*>("mybtn");
- qDebug()<< window <<"|"<< window->objectName();
- qDebug()<< btn <<"|"<< btn->objectName();
- // 方式三
- QObject::connect(window,SIGNAL(qmlSig(int,QString) ),MyObject::getInst(),SLOT(cppSlot(int,QString)) );
- QObject::connect(MyObject::getInst(),SIGNAL(cppSig(QVariant,QVariant) ),window,SLOT(qmlSlot(QVariant,QVariant) ) );
- return app.exec();
- }
复制代码 main.qml
- import QtQuick 2.12
- import QtQuick.Window 2.12
- import QtQuick.Controls 2.12
- import MyObj 1.0
- Window {
- id:window
- visible: true
- width:600
- height: 400
- objectName: "mywindow"
- title: qsTr("QML与C++交互")
- signal qmlSig(int i,string s)
- MyObject{ //C++中的对象。
- id:myobj
- iValue: 1
- m_sString: "m_sString_test"
- }
- Button{
- objectName: "mybtn"
- onClicked: {
- console.log("click")
- myobj.fun() //MyObject.fun()
- }
- }
- function qmlSlot(i,s){ // 参数类型 对应cpp端 都是QVariant
- console.log(i,s);
- }
- Connections{
- target: myobj
- onCppSig:{
- console.log(i,s);
- }
- // function onCppSig(i,s){
- // qmlSlot(i,s)
- // }
- }
- }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |