当前位置: 首页 > article >正文

qml调用c++类内函数的三种方法

一.方法一:使用 Q_INVOKABLE 宏声明成员函数

1.第一步:依然需要新建一个类NetworkHandler:   

#include <QObject>

class NetworkHandler : public QObject

{

    Q_OBJECT

public:

    explicit NetworkHandler(QObject *parent = nullptr);

    Q_INVOKABLE void onConnetClicked();

    Q_INVOKABLE void onTestClicked();

    Q_INVOKABLE void setValue(int newValue);

    Q_INVOKABLE int getValue();

signals:

     void valueChanged(int value);

     void kkYUy(QString str);

private slots:

    void networ_slots();

};

注意:依然需要使用 Q_INVOKABLE 这个宏声明成员函数,将函数申明为元对象系统可调用的函数,Q_INVOKABLE声明后的函数即可在qml中调用。

2.第二步:在main.cpp中进行注册:

#include <QQmlContext>

#include <QQmlEngine>

#include "network.h"

int main(int argc, char *argv[])

{

    set_qt_environment();

    QGuiApplication app(argc, argv);

    qmlRegisterType<NetworkHandler>("NetLibrary", 1, 0, "NetworkHandler");

    QQmlApplicationEngine engine;

    const QUrl url(u"qrc:/qt/qml/Main/main.qml"_qs);

    QObject::connect(

        &engine,

        &QQmlApplicationEngine::objectCreated,

        &app,

        [url](QObject *obj, const QUrl &objUrl) {

            if (!obj && url == objUrl)

                QCoreApplication::exit(-1);

        },

        Qt::QueuedConnection);

    engine.addImportPath(QCoreApplication::applicationDirPath() + "/qml");

    engine.addImportPath(":/");

    engine.load(url);

    if (engine.rootObjects().isEmpty()) {

        return -1;

    }

    return app.exec();

}

注册语句:qmlRegisterType<NetworkHandler>("NetLibrary", 1, 0, "NetworkHandler");

其中NetLibrary是QML中的组件名,1.0是组件版本号,NetworkHandler是用于QML中的类名。

第三步:修改一下QML文件:

import QtQuick 6.0

import QtQuick.Controls 6.0

import NetLibrary 1.0

ApplicationWindow {

    visible: true

    width: 640

    height: 480

    title: qsTr("QML Button Example")

    Column  {

        id: buttonRow

        anchors.fill: parent

        spacing: 20

        NetworkHandler{

        id:networkClass

        }

        Button {

            id: button1

            text: qsTr("button1")

            onClicked: {

                console.log("Button clicked12!")

                networkClass.onConnetClicked()

                networkClass.setValue(1)

                button1.text = qsTr("Clicked1!")

            }

        }

    }

}

说明:

import NetLibrary 1.0 是在 main.cpp中进行注册了类型的版本化命名空间。

导入之后,就可以如下所示 调用NetworkHandler进行实例化,并设置id为networkClass:    

NetworkHandler

{

id:networkClass

}

在两个button的点击事件中,就能通过 实例化对象 networkClass调用 第一步 被 Q_INVOKABLE声明的函数了。

二.方式二:信号槽方式

1.第一步:依然需要新建一个类NetworkHandler:   

#include <QObject>

class NetworkHandler : public QObject

{

    Q_OBJECT

public:

    explicit NetworkHandler(QObject *parent = nullptr);

    Q_INVOKABLE void onConnetClicked();

    Q_INVOKABLE void onTestClicked();

    Q_INVOKABLE void setValue(int newValue);

    Q_INVOKABLE int getValue();

signals:

     void valueChanged(int value);

     void kkYUy(QString str);

private slots:

    void networ_slots();

};

注意:信号函数前不用加入Q_INVOKABLE宏

2.第二步:在main.cpp中进行注册:

#include <QQmlContext>

#include <QQmlEngine>

#include "network.h"

int main(int argc, char *argv[])

{

    set_qt_environment();

    QGuiApplication app(argc, argv);

    qmlRegisterType<NetworkHandler>("NetLibrary", 1, 0, "NetworkHandler");

    QQmlApplicationEngine engine;

    const QUrl url(u"qrc:/qt/qml/Main/main.qml"_qs);

    QObject::connect(

        &engine,

        &QQmlApplicationEngine::objectCreated,

        &app,

        [url](QObject *obj, const QUrl &objUrl) {

            if (!obj && url == objUrl)

                QCoreApplication::exit(-1);

        },

        Qt::QueuedConnection);

    engine.addImportPath(QCoreApplication::applicationDirPath() + "/qml");

    engine.addImportPath(":/");

    engine.load(url);

    if (engine.rootObjects().isEmpty()) {

        return -1;

    }

    return app.exec();

}

注册语句:qmlRegisterType<NetworkHandler>("NetLibrary", 1, 0, "NetworkHandler");

其中NetLibrary是QML中的组件名,1.0是组件版本号,NetworkHandler是用于QML中的类名。

第三步:修改一下QML文件:

import QtQuick 6.0

import QtQuick.Controls 6.0

import NetLibrary 1.0

ApplicationWindow {

    visible: true

    width: 640

    height: 480

    title: qsTr("QML Button Example")

    Column  {

        id: buttonRow

        anchors.fill: parent

        spacing: 20

        NetworkHandler{

        id:networkClass

        }

        Connections{  //信号-槽连接

            target: networkClass

            function onValueChanged(value){

                console.log("/*-----------收到信号----------*/")

                console.log(value)

            }

        }

        Button {

            id: button1

            text: qsTr("button1")

            onClicked: {

                console.log("Button clicked12!")

                networkClass.onConnetClicked()

                networkClass.setValue(1)

                button1.text = qsTr("Clicked1!")

            }

        }

    }

}

说明:定义一个槽函数来接收c++中发送过来的信号

        Connections{  //信号-槽连接

            target: networkClass

            function onValueChanged(value){

                console.log("/*-----------收到信号----------*/")

                console.log(value)

            }

        }

注意:在c++类中定义的信号是  valueChanged(),在Qml中进行监听 需要在前面加 "on",首字母大写,变为onValueChanged:{}

三.方式三:通过Q_PROPERTY宏来实现

1.第一步:依然需要新建一个类MyClass:   

#include <QDebug>

#include <QObject>

class MyClass : public QObject

{

    Q_OBJECT

    Q_PROPERTY(int value READ getValue WRITE setValue NOTIFY valueChanged)

public:

    MyClass(QObject *parent = nullptr) : QObject(parent), m_value(0) {}

    int getValue() const {

         qDebug()<<"MyClass--------getValue-----:"<<m_value;

        return m_value;

    }

    void setValue(int value) {

        if (m_value != value) {

            m_value = value;

            qDebug()<<"MyClass--------setValue-----:"<<m_value;

            emit valueChanged(m_value);

        }

    }

signals:

    void valueChanged(int newValue);

private:

    int m_value;

};

说明:

Q_PROPERTY(int value READ getValue WRITE setValue NOTIFY valueChanged)  是 Qt 开发框架中的一个宏定义,用于在 QObject 的派生类中声明一个属性,

并为该属性提供读写接口以及属性值变化时的通知信号。

声明属性:

通过 Q_PROPERTY 宏,可以在 QObject 的派生类中声明一个名为 value 的属性。

该属性可以被 Qt 的属性系统识别和访问。

提供读写接口:

READ getValue 指定了读取 value 属性值的函数 getValue。

WRITE setValue 指定了设置 value 属性值的函数 setValue。

这两个函数分别用于获取和设置属性的值,从而实现了对属性值的封装和保护。

属性变化通知:

NOTIFY valueChanged 指定了当 value 属性值发生变化时发出的通知信号 valueChanged。

这允许其他对象或组件在属性值变化时采取相应的行动,如更新界面或触发其他逻辑。

注意:

     这种方式只能修改类的一个属性值,一般类型比较简单,就是int、QString这种;如果需要调用类的自定方法建议还是用方式一中的Q_INVOKABLE宏方式。

2.第二步:在main.cpp中进行注册:

#include "test.h"

int main(int argc, char *argv[])

{

    set_qt_environment();

    QGuiApplication app(argc, argv);

    qmlRegisterType<MyClass>("MyLibrary", 1, 0, "MyClass");

    QQmlApplicationEngine engine;

    const QUrl url(u"qrc:/qt/qml/Main/main.qml"_qs);

    QObject::connect(

        &engine,

        &QQmlApplicationEngine::objectCreated,

        &app,

        [url](QObject *obj, const QUrl &objUrl) {

            if (!obj && url == objUrl)

                QCoreApplication::exit(-1);

        },

        Qt::QueuedConnection);

    engine.addImportPath(QCoreApplication::applicationDirPath() + "/qml");

    engine.addImportPath(":/");

    engine.load(url);

    if (engine.rootObjects().isEmpty()) {

        return -1;

    }

    return app.exec();

}

注册语句:qmlRegisterType<MyClass>("MyLibrary", 1, 0, "MyClass");

第三步:修改一下QML文件:

import QtQuick 6.0

import QtQuick.Controls 6.0

import MyLibrary 1.0

ApplicationWindow {

    visible: true

    width: 640

    height: 480

    title: qsTr("QML Button Example")

    Column  {

        id: buttonRow

        anchors.fill: parent

        spacing: 20

        MyClass{

        id:myClass

        }

        Button {

            id: button1

            text: qsTr("button1")

            onClicked: {

                console.log("Button clicked12!")

                console.log("myClass.value:",myClass.value)

                myClass.value=2

                button1.text = qsTr("Clicked1!")

            }

        }

    }

}

调用语句:

console.log("myClass.value:",myClass.value)  //获取value值

myClass.value=2   //设置value值

运行后log输出:

MyClass--------getValue-----: 0

qml: myClass.value: 0

MyClass--------setValue-----: 2


http://www.kler.cn/a/414276.html

相关文章:

  • git 学习笔记
  • 如何正确使用 GitHub API 获取特定版本信息:详解错误排查与解决方案
  • Java基础面试题07:finalize() 方法什么时候被调用?析构函数(finalization)的目的是什么?
  • vue3+vite使用vite-plugin-electron-renderer插件和script-loader插件有冲突
  • 九、Ubuntu Linux操作系统
  • python控制鼠标,键盘,adb
  • 操作系统的设计哲学:Linux与Windows的对比
  • CRMEB 多商户PHP版 v3.1更新内容
  • 探索运维新视界,CMDB的3D机房功能深度解析
  • JVM(七、性能监控、故障处理工具)
  • vue安装步骤
  • JVM指令集概览:基础与应用
  • 讲懂http和https
  • 【AI技术赋能有限元分析应用实践】Abaqus有限元分析与深度学习结合20个案例与有限元分析数据来源方法说明
  • 相交链表和环形链表
  • 力扣做题笔记
  • shell编程5,字符串运算符
  • Sofia-SIP 使用教程
  • 调试android P2P无法正常运行
  • Cesium着色器的创意和方法(六——透明和半透明)
  • linux线程资源回收
  • Lombok :简化 Java 编程的得力工具
  • Rust学习笔记_04——引用
  • 鸿蒙学习统一上架与多端分发-快速上架(1)
  • 交通流量预测:基于交通流量数据建立模型
  • 【后端面试总结】Redis持久化