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); #endifQGuiApplication 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.0Rectangle{width: 200height: 200//相当于 实列化一个C++对象HTTPHandler{id:httpHandler}signal loginOk()Row{anchors.centerIn: parentTextField{id:name}TextField{id:pwd}}Button{anchors.bottom: parent.bottomtext: 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.0Rectangle{width: 200height: 200//相当于 实列化一个C++对象HTTPHandler{id:httpHandler//绑定C++信号onLoginSuccess: {loginOk()}}signal loginOk()Row{anchors.centerIn: parentTextField{id:name}TextField{id:pwd}}Button{anchors.bottom: parent.bottomtext: 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.0Rectangle{width: 200height: 200//相当于 实列化一个C++对象HTTPHandler{id:httpHandler}signal loginOk()Row{anchors.centerIn: parentTextField{id:name}TextField{id:pwd}}//定义一个文本框 直接绑定C++的属性Text {anchors.top: parent.toptext: httpHandler.status}Button{anchors.bottom: parent.bottomtext: qsTr("登录")onClicked: {//调用C++对象中的函数if(httpHandler.login(name.text,pwd.text)){loginOk()}}} }
3,看下效果
点击登录 ,如果密码或用户名错误会将C++的状态信息,实时的显示到左上角的QML Text控件中。来这里看(QML与C++交互 | Qt 你好)