C++与QML 信号与槽交互

这篇具有很好参考价值的文章主要介绍了C++与QML 信号与槽交互。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、全局属性

在main.cpp中通过 QQmlApplicationEngine engine 获得全局对象

QQmlApplicationEngine engine;    
//全局对象  上下文对象    
QQmlContext* context = engine.rootContext();      
 //获取屏幕的大小     
Screen *screen= QGuiApplication::primaryScreen();     
QRect rect=   screen->virtualGeometry(); //整个屏幕的大小     
//注册的上下文对象 它是作用于全局 有重命名的风险     
context->setContextProperty("SCREEN_WIDTH",rect.width()/2); //设置全局属性 所有QMl文件都能访问得到的

在qml中使用  SCREEN_WIDTH  全局属性

 width: SCREEN_WIDTH    //screen.desktopAvailableWidth 获取整个屏幕的宽度

二,创建自定义对象,在QMl中使用

1.创建一个MyObject类

qml绑定c++信号,C++,c++,qml

 2.在myobject.h中定义一些属性,以便在qml中可以使用 并为每个属性添加读写的方法和相应的信号

class MyObject : public QObject
{    Q_OBJECT
      public:   
       explicit MyObject(QObject *parent = nullptr);    
      int iValue() const;
   void setIValue(int iValue);
   QString sString() const;    
  void setSString(const QString &sString);    
//定义一个函数 加Q_INVOKABLE 就可以让qml访问    
Q_INVOKABLE void  func();

private:    
//生成get 和set 方法   
 int m_iValue;   
 QString m_sString;  
 
//宏    
//第一种方式    
//声明一个名称 int iValue  想是QMl 中width    
//READ iValue --->通过那个函数读的    
// WRITE setIValue---》通过那个函数写的    
//NOTIFY iValueChanged 当前这个值修改会发出iValueChanged信号   
/* Q_PROPERTY(int iValue READ iValue WRITE setIValue NOTIFY iValueChanged)    Q_PROPERTY(QString sString READ sString WRITE setSString NOTIFY sStringChanged)*/   //第二种方式   
 Q_PROPERTY(int iValue MEMBER m_iValue NOTIFY iValueChanged)    
Q_PROPERTY(QString sString MEMBER m_sString NOTIFY sStringChanged)

public slots:    
//槽函数    
void ccpSlot(int i,QString str); 
signals:    
void iValueChanged();    
void sStringChanged();    
//定义一个信号,在qml中绑定槽函数    
void cppSig(QVariant i,QVariant s);
};

2.在myobject.cpp中实现

#include "myobject.h"

MyObject::MyObject(QObject *parent) : QObject(parent)
{

}

MyObject *MyObject::getInstance()
{
    static MyObject * obj = new MyObject();
    return obj;
}

int MyObject::iValue() const
{
    return m_iValue;
}

void MyObject::setIValue(int iValue)
{
    if(m_iValue == iValue)
        return;

    m_iValue = iValue;
    //发出信号
    emit iValueChanged();
}

QString MyObject::sString() const
{
    return m_sString;
}

void MyObject::setSString(const QString &sString)
{
    if(m_sString == sString)
        return;
    m_sString = sString;
    emit sStringChanged();
}

void MyObject::func()
{
    emit cppSig(101,"王五"); //发送信号
    qDebug()<<__FUNCTION__;//当前函数名称

}

void MyObject::ccpSlot(int i, QString str)
{
     qDebug()<<__FUNCTION__<<"  "<<i<<" "<<str;
}

3.在main.cpp中访问 定义这个复杂的类型

有两种方式

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QScreen>
#include <myobject.h>
#include <QObject>
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->virtualGeometry(); //整个屏幕的大小
     //注册的上下文对象 它是作用于全局 有重命名的风险
     context->setContextProperty("SCREEN_WIDTH",rect.width()/2); //设置全局属性 所有QMl文件都能访问得到的
   
 //qml中就可以访问这个对象myObjectOO
     //但是qml 并不能认识这个这个复杂的类型

     //方式一
     //context->setContextProperty("myObjectOO",MyObject::getInstance());//一般不用这个方法

     //方式二
     //四个参数
     //第一个参数是qml中导入的名称 import HelloMyObj 1.0
     //第二个第三个参数分别是主次版本号;第四个指的是QML中类的名字。
     //qmlRegisterType<MyObject>("HelloMyObj",1,0,"MyObject");
     //我们一定要通过创建对象来定义一个我们自定义的object

     //创建一个全局的单例的模式
     qmlRegisterSingletonInstance("HelloMyObj",1,0,"MyObject",MyObject::getInstance());


///
    //地址
    const QUrl url(QStringLiteral("qrc:/CPPSlotSignal.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);

/
    //C++端绑定qml中发出的信号
    //engine 加载完成后 load以后
    auto list = engine.rootObjects(); //返回CPPSlotSignal.qml 中所有的对象
    //auto objectName = list.first()->objectName();
   // auto btnName = list.first()->findChild<QObject *>("btnClick");
   // qDebug()<<btnName;
    auto window = list.first();
    //绑定
    QObject::connect(window,SIGNAL(qmlSig(int,QString)),
                     MyObject::getInstance(),SLOT(ccpSlot(int,QString)));
    //绑定
    QObject::connect(MyObject::getInstance(),SIGNAL(cppSig(QVariant,QVariant)),
                    window,SLOT(qmlSlot(QVariant,QVariant)));

///
    return app.exec();
}

4.在qml中访问

需要导入对象名和主次版本号 ,才能正式使用

import HelloMyObj 1.0

import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Controls 2.12

import HelloMyObj 1.0

Window {
    id: window

    property int value: myobj.ivalue
    visible: true
    width: 640
    height: 480
    title: qsTr("hello")


  MyObject{
       id: myobj

       iValue:20

      sString:"hello"
  }

onValueChanged:

{

  console.log(value)

}

Button{

onClicked: {

   myobj.iValue = 20

}


}

三、QML端发送信号,绑定c++端的函数

1.在qml写好信号,并发出

Window {    
id: window   
 objectName: "window"   
 visible: true   
 width: 640    
height: 480    
title: qsTr("QML端发送信号,绑定c++端的函数")
//信号   
 signal qmlSig(int i,string s)   
 Button {        
 objectName: "btnClick"        
onClicked: {           
  //发送信号          
 qmlSig(22,"hello")           
       
}    
}

2.在类中定义槽函数

public slots:    
//槽函数    
void ccpSlot(int i,QString str);

实现

void MyObject::ccpSlot(int i, QString str)
{    
 qDebug()<<__FUNCTION__<<"  "<<i<<" "<<str;
}

3.绑定信号与槽函数

3.1在main.cpp绑定----C++端绑定qml中发出的信号

//engine 加载完成后 load以后    
auto list = engine.rootObjects(); //返回CPPSlotSignal.qml 中所有的对象    
//auto objectName = list.first()->objectName();   
// auto btnName = list.first()->findChild<QObject *>("btnClick");   
// qDebug()<<btnName;    
auto window = list.first();    
//绑定    
QObject::connect(window,SIGNAL(qmlSig(int,QString)),                                    MyObject::getInstance(),SLOT(ccpSlot(int,QString)));

3.2在qml端绑定C++类的槽函数  两种方式

 MyObject{
 id: myobj
 }    
//连接C++中槽函数    
//1.   
 /*Connections{        
target: window //发出者        
function onQmlSig(i,str){           
 myobj.ccpSlot(i,str)        
}    
} 
 */   
 //2.在组件完成时与连接   
/* Component.onCompleted: {       
 qmlSig.connect(myobj.ccpSlot)    
}    */

四、c++端发出信号,qml端绑定槽函数

1.myobject.h的定义信号

//定义一个信号,在qml中绑定槽函数   
 void cppSig(QVariant i,QVariant s);

2.在qml中定义槽函数

    function qmlSlot(i,s){  // 参数类型 对应CPP端 都是QVariant                   console.log("qml",i,s)    
}

3.绑定

3.1c++端绑定

auto list = engine.rootObjects();
auto window = list.first(); QObject::connect(MyObject::getInstance(),SIGNAL(cppSig(QVariant,QVariant)),                      window,SLOT(qmlSlot(QVariant,QVariant)));

3.2qml端绑定

Connections{            
target: MyObject //发出者            
function onCppSig(i,str){               
 qmlSlot(i,str)       
     }

4.可以不用在qml实现MyObject 对象,只需要在main中创建一个全局的单例的模式

 qmlRegisterSingletonInstance("HelloMyObj",1,0,"MyObject",MyObject::getInstance());

五、C++端直接调用QML函数

1.qml中写函数


    function qmlFunc(i,s){
        return " are you ok?"
    }

2.在main.cpp中调用

auto list = engine.rootObjects(); //返回CPPSlotSignal.qml 中所有的对象
auto window = list.first();
//调用QML端的函数    
//第一参数,拥有者  第二参数 函数名称 第三参数 保存到哪  后面就是要传递的参数   
 QVariant resFunc;    
QVariant arg_1 = 123;    
QVariant arg_2 = "I am fine ";    
QMetaObject::invokeMethod(window,"qmlFunc",                              Q_RETURN_ARG(QVariant,resFunc),                                     Q_ARG(QVariant,arg_1),     
Q_ARG(QVariant,arg_2));
qDebug()<<"res = "<<resFunc;

3.在qml中调用c++中的函数

3.1在myobject.h中定义

//定义一个函数 加Q_INVOKABLE 就可以让qml访问    
Q_INVOKABLE void  func();

3.2在qml中使用文章来源地址https://www.toymoban.com/news/detail-579499.html

 Button {        
objectName: "btnClick"       
 onClicked: {  
 MyObject.func()       
 }    
}

到了这里,关于C++与QML 信号与槽交互的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • qml与C++的交互

    qml端使用C++对象类型、qml端调用C++函数/c++端调用qml端函数、qml端发信号-连接C++端槽函数、C++端发信号-连接qml端函数等。 代码资源下载: https://download.csdn.net/download/TianYanRen111/88779433 若无法下载,直接拷贝以下代码测试即可。 main.cpp MyObject.h MyObject.cpp TestObject.h main.qml 参考文

    2024年01月25日
    浏览(35)
  • QML与C++交互详解

    在现代软件开发中,图形用户界面(GUI)是用户与程序交互的重要组成部分。Qt框架提供了一种强大的方式来构建跨平台的GUI应用程序,其中QML(Qt Meta-Object Language)和C++的交互是一个重要的主题。本篇博文将深入探讨如何在QML中创建和操作C++对象,实现双向的交互。 在Qt中,

    2024年01月20日
    浏览(27)
  • QML 与C++交互详解

    1.思维导图 2.调用全局变量 在C++中直接定义全局变量,QML中能够直接访问。 使用engine.rootContext()-setContextProperty(\\\"WIDTH\\\",300),设置了一个全局变量WIDTH。 QML中直接访问WIDTH。  3.QML中调用C++类型 自定义一个C++类 MyObject 对象,有两个成员变量m_value和m_str,分别对应一个set和一个

    2024年02月02日
    浏览(26)
  • 【Qt- C++ & Qml 交互】

    2024年01月10日
    浏览(55)
  • QT C++类与QML交互

    C++方负责数据,QML负责显示,先准备工作如下: (1)新建一个数据类,继承至QObject class Cdata : public QObject (2)将有交互关系的数据,加入到类的私有成员中 private: int iNum; QString strEdit; (3)给此成员Q_PROPERTY和相应的函数实现(ALT+回车可自动创建) Q_PROPERTY(int iNum READ getINum W

    2024年02月04日
    浏览(31)
  • QML与C++的交互操作

      QML旨在通过C ++代码轻松扩展。Qt QML模块中的类使QML对象能够从C ++加载和操作,QML引擎与Qt 元对象系统 集成的本质使得C ++功能可以直接从QML调用。这允许开发混合应用程序,这些应用程序是通过混合使用QML,JavaScript和C ++代码实现的。除了从QML访问C ++功能的能力之外,Qt

    2024年02月09日
    浏览(29)
  • Qt开发教程:C++与QML的交互

    Qt是一个功能强大的跨平台应用程序开发框架,支持同时使用C++和QML来开发应用程序。通过C++与QML的交互,我们可以实现更灵活、更强大的应用程序。本文将详细介绍如何在Qt中创建自定义对象、在QML端发送信号并绑定到C++端、在C++端发送信号并绑定到QML端、以及实现QML端直接

    2024年04月16日
    浏览(46)
  • QML、C++ 和 JS 三者之间的交互

    QML、C++ 和 JS 三者之间的交互是 Qt Quick 应用开发的核心。以下是它们之间交互的常见方式: 从 QML 调用 C++ 函数 要从 QML 调用 C++ 函数,您可以使用 Qt 的 QML 注册机制,例如 qmlRegisterType ,将 C++ 类注册为 QML 类型。 C++ 代码:

    2024年02月07日
    浏览(28)
  • 在Qt中实现C++与QML的交互

    Qt是一个功能强大的跨平台应用程序开发框架,支持同时使用C++和QML来开发应用程序。通过C++与QML的交互,我们可以实现更灵活、更强大的应用程序。本文将详细介绍如何在Qt中创建自定义对象、在QML端发送信号并绑定到C++端、在C++端发送信号并绑定到QML端、以及实现QML端直接

    2024年02月09日
    浏览(35)
  • C++自定义信号和QML的槽函数建立连接

    0x00 在C++代码在定义一个信号函数:“void sendData2UI(QString msg);”,该函数主要是将接收到的UDP消息发送到QML界面中 0x01 在QML代码中使用Connections创建C++对象的信号与QML中定义的槽函数连接 效果演示:

    2024年02月16日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包