QML与C++交互

Qt 你好 | 专注于Qt的技术分享平台

QML写界面,业务逻辑使用C++,既能快速的开发界面也能利用C++的强大生态,这是目前比较被认可的方式,那就涉及到QML与C++对象的交互。

我们以登录例子来说明,页面点击登录,将信息传递到c++ http对象进行密码的验证,然后返回登录结果。

一,调用C++中的函数

1,普通C++类

复制代码
#ifndef HTTPHANDLER_H
#define HTTPHANDLER_H

#include <QObject>
class HTTPHandler:public QObject{
    Q_OBJECT
public:
    HTTPHandler(QObject* parent=0):QObject(parent){

    }
    //登录接口 验证用户名 和密码
    Q_INVOKABLE bool login(QString name,QString pwd){
        if(name=="admin"&&pwd=="123"){
            return true;
        }else{
            return false;
        }
    }
};
#endif // HTTPHANDLER_H

2,注册C++ 类

main.cpp注册此 C++ 类型,这样QML中就能使用了。

复制代码
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "HTTPHandler.h"

int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
    QGuiApplication app(argc, argv);

    //注册类型
    qmlRegisterType<HTTPHandler>("HTTPHandler", 1, 0, "HTTPHandler");


    QQmlApplicationEngine engine;
    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();
}

3,调用C++对象中的函数

只要是C++中 通过Q_INVOKABLE关键词声明的public函数,QML中都能访问。

复制代码
import QtQuick 2.15
import QtQuick.Controls 1.4
//导入C++ 对象
import HTTPHandler 1.0

Rectangle{
    width: 200
    height: 200

    //相当于 实列化一个C++对象
    HTTPHandler{
        id:httpHandler
    }

    signal loginOk()
    Row{
        anchors.centerIn: parent
        TextField{
            id:name
        }
        TextField{
            id:pwd
        }
    }
    Button{
        anchors.bottom: parent.bottom
        text: qsTr("登录")
        onClicked: {
            //调用C++对象中的函数
            if(httpHandler.login(name.text,pwd.text)){
                loginOk()
            }
        }
    }
}

二,响应C++中的信号

上述方式相当于同步的方式调用C++中的函数,还可以异步的响应C++中的信号,相当于QML中的槽与C++中的信号进行绑定。

1,C++类

复制代码
#ifndef HTTPHANDLER_H
#define HTTPHANDLER_H

#include <QObject>
class HTTPHandler:public QObject{
    Q_OBJECT
public:
    HTTPHandler(QObject* parent=0):QObject(parent){

    }

    Q_INVOKABLE void login(QString name,QString pwd){
        if(name=="admin"&&pwd=="123"){
            //验证成功后 激发信号
            emit loginSuccess();
        }
    }

signals:
    //登录成功信号
    void loginSuccess();
};
#endif // HTTPHANDLER_H

2,响应C++信号

复制代码
import QtQuick 2.15
import QtQuick.Controls 1.4
import HTTPHandler 1.0

Rectangle{
    width: 200
    height: 200

    //相当于 实列化一个C++对象
    HTTPHandler{
        id:httpHandler
        //绑定C++信号
        onLoginSuccess: {
            loginOk()
        }
    }

    signal loginOk()
    Row{
        anchors.centerIn: parent
        TextField{
            id:name
        }
        TextField{
            id:pwd
        }
    }
    Button{
        anchors.bottom: parent.bottom
        text: qsTr("登录")
        onClicked: {
            //调用C++对象中的函数
            httpHandler.login(name.text,pwd.text)

        }
    }
}

三,绑定C++中的属性

还可以直接在C++定义属性,然后QML绑定此属性,适合实时的传递一些状态数据。

1,C++类

复制代码
#ifndef HTTPHANDLER_H
#define HTTPHANDLER_H

#include <QObject>
class HTTPHandler:public QObject{
    Q_OBJECT
    //注册属性
    Q_PROPERTY(QString status READ getStatus WRITE setStatus NOTIFY statusChanged FINAL)

public:
    HTTPHandler(QObject* parent=0):QObject(parent){

    }

    Q_INVOKABLE bool login(QString name,QString pwd){
        if(name=="admin"&&pwd=="123"){
            return true;
        }else{
            //设置状态信息
            setStatus("pwd or name error");
        }
    }

    QString getStatus() const;
    void setStatus(const QString &newStatus);

signals:
    void statusChanged();

private:
    //状态信息
    QString status;
};

inline QString HTTPHandler::getStatus() const
{
    return status;
}

inline void HTTPHandler::setStatus(const QString &newStatus)
{
    if (status == newStatus)
        return;
    status = newStatus;
    emit statusChanged();
}


#endif // HTTPHANDLER_H

2,绑定属性

复制代码
import QtQuick 2.15
import QtQuick.Controls 1.4
import HTTPHandler 1.0

Rectangle{
    width: 200
    height: 200

    //相当于 实列化一个C++对象
    HTTPHandler{
        id:httpHandler
    }

    signal loginOk()
    Row{
        anchors.centerIn: parent
        TextField{
            id:name
        }
        TextField{
            id:pwd
        }
    }

    //定义一个文本框 直接绑定C++的属性
    Text {
        anchors.top: parent.top
        text: httpHandler.status
    }
    Button{
        anchors.bottom: parent.bottom
        text: qsTr("登录")
        onClicked: {
            //调用C++对象中的函数
            if(httpHandler.login(name.text,pwd.text)){
                loginOk()
            }
        }
    }
}

3,看下效果

点击登录 ,如果密码或用户名错误会将C++的状态信息,实时的显示到左上角的QML Text控件中。来这里看(QML与C++交互 | Qt 你好)

相关推荐
Kimi-学长1 分钟前
PHP 爆出两个高危安全漏洞!CVE-2026-109618、CVE-2026-109619 修复方案与防护指南
开发语言·php
“AI国潮设计-小江”5 分钟前
《【AIGC实战】Python+SDXL批量生成“英歌舞草莓抱抱卷蛋糕”IP插牌立牌方案,锁定角色一致性,甜品插件化落地》
开发语言·人工智能·python·prompt·aigc
Ivanqhz6 分钟前
超参数考量与设计
数据库·人工智能·深度学习·算法·机器学习
雪落漂泊6 分钟前
C++算法 滑动窗口篇(上)
开发语言·c++·算法
估值探索者10 分钟前
【Python量化技术指标实战 04】布林带通道突破,怎么知道是真突破还是假突破?
java·开发语言·python·接口·股票数据api接口
Soneswy11 分钟前
C++基础篇——类与对象(上)
开发语言·c++
张小姐的猫13 分钟前
【MySQL】表的约束
android·linux·服务器·数据库·c++·mysql·adb
kiracrimson17 分钟前
STL简单引入:把数据结构做成模板
开发语言·数据结构·c++
爱吃牛肉的大老虎19 分钟前
Redis之分布式 Session问题
数据库·redis·分布式
fanruitian21 分钟前
python property
开发语言·python