QML与C++交互:登陆界面设计
本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.
环境:
主机:WIN7
开发环境:Qt5.2.1
说明:
QML设计前台界面,C++后台负责逻辑
效果图:
源代码:
前台qml文件
login.qml
- /*********************************************************************
- * 登陆界面qml文件
- * (c)copyright 2014,jdh
- * All Right Reserved
- *新建日期:2014/4/29 by jdh
- *修改日期:2014/4/30 by jdh
- *修改日期:2014/5/4 by jdh
- *修改日期:2014/5/5 by jdh
- **********************************************************************/
- import QtQuick 2.0
- import "content"
- import Login_Gui 1.0
- Rectangle
- {
- id: login
- 320; height: 512
- SystemPalette { id: activePalette }
- //C++组件:用户界面
- Login_Gui
- {
- id:login_gui
- onSig_login_result:
- {
- //关闭登陆动画
- load_gif.opacity = 0
- //根据登陆结果处理
- switch (result)
- {
- //登陆成功
- case 0:
- message.text = "登陆成功"
- message.opacity = 1
- break;
- //无此用户名
- case 1:
- message.text = "登陆失败:无此用户名"
- message.opacity = 1
- break;
- //密码错误
- case 2:
- message.text = "登陆失败:密码错误"
- message.opacity = 1
- break;
- //达到最大登陆次数
- case 3:
- message.text = "登陆失败:达到最大登陆次数"
- message.opacity = 1
- break;
- }
- }
- }
- //背景图片
- Image
- {
- id: background
- anchors { top: parent.top; bottom: parent.bottom }
- anchors.fill: parent
- source: "pics/pic1.png"
- fillMode: Image.PreserveAspectCrop
- }
- //消息框
- Message
- {
- id: message
- font_size: login.height * 0.03
- anchors {centerIn: parent}
- opacity: 0
- }
- //登陆动画
- AnimatedImage
- {
- id: load_gif; source: "pics/load.gif"
- anchors {horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter}
- z: 100
- opacity: 0
- }
- //顶栏
- Item
- {
- id: top_bar
- login.width; height: login.height * 0.06
- anchors.top: parent.top
- Text
- {
- id: title
- anchors { top: parent.top; horizontalCenter: parent.horizontalCenter }
- //text: "登陆"
- text: "登陆"
- font.bold: true
- font.pointSize: login.height * 0.06 * 0.4
- color: "dark red"
- }
- }
- //空白栏
- Item
- {
- id: space1
- login.width; height: login.height * 0.1
- anchors.top: top_bar.bottom
- }
- //登陆框
- Rectangle
- {
- id: rect1
- login.width * 0.8; height: login.height * 0.3
- anchors { top: space1.bottom; horizontalCenter: parent.horizontalCenter }
- border.color: "#707070"
- color: "transparent"
- radius: 8
- Row
- {
- spacing: rect1.width * 0.05
- Item
- {
- rect1.width * 0.05; height: rect1.height
- }
- Column
- {
- spacing: rect1.height * 0.025
- Item
- {
- rect1.width * 0.8; height: rect1.height * 0.05
- }
- LineInput
- {
- id: txt_user_id
- rect1.width * 0.8; height: rect1.height * 0.2
- font_size:height * 0.7
- //anchors {horizontalCenter: rect1.horizontalCenter; top: rect1.top; topMargin: 8}
- hint: "请输入用户号"
- text:login_gui.user_id
- }
- LineInput
- {
- id: txt_password
- rect1.width * 0.8; height: rect1.height * 0.2
- font_size:height * 0.7
- //anchors {horizontalCenter: rect1.horizontalCenter; bottom: btn_login.top; bottomMargin: rect1.height * 0.1}
- hint: "请输入密码"
- text:login_gui.password
- }
- Row
- {
- spacing: rect1.width * 0.1
- Button
- {
- id: btn_login
- rect1.width * 0.35; height: rect1.height * 0.2
- //anchors { left: rect1.left; leftMargin: 28; bottom: rect1.bottom; bottomMargin: 8 }
- text: "登陆"
- onClicked: login_req()
- }
- Button
- {
- id: btn_quit
- rect1.width * 0.35; height: rect1.height * 0.2
- //anchors { right: rect1.right; rightMargin: 28; bottom: rect1.bottom; bottomMargin: 8 }
- text: "退出"
- onClicked:
- {
- Qt.quit();
- }
- }
- }
- Row
- {
- spacing: rect1.width * 0.1
- CheckBox
- {
- id: check1
- rect1.width * 0.35; height: rect1.height * 0.2
- //anchors { left: rect1.left; top: rect1.bottom }
- caption: "记住密码"
- selected: login_gui.flag_remember
- }
- CheckBox
- {
- id: check2
- rect1.width * 0.35; height: rect1.height * 0.2
- //anchors { right: rect1.right; top: rect1.bottom }
- caption: "自动登陆"
- selected: login_gui.flag_auto
- }
- }
- }
- }
- }
- //android自带键处理
- FocusScope
- {
- focus: true
- Keys.onReleased:
- {
- if (event.key == Qt.Key_Back)
- {
- console.log("qml login quit")
- login.sig_btn_quit()
- }
- }
- }
- //登陆请求函数
- function login_req()
- {
- //判断用户名是否有效
- if (txt_user_id.text == "")
- {
- message.text = "请输入用户名"
- message.opacity = 1
- return
- }
- //判断密码是否有效
- if (txt_password.text == "")
- {
- message.text = "请输入密码"
- message.opacity = 1
- return
- }
- //显示登陆动画
- load_gif.opacity = 1
- //登陆请求
- login_gui.user_id = txt_user_id.text
- login_gui.password = txt_password.text
- login_gui.flag_remember = check1.selected
- login_gui.flag_auto = check2.selected
- login_gui.slot_login_req()
- }
- // //信号槽绑定
- // Component.onCompleted:
- // {
- // login_gui.sig_user_id_changed.connect(login_gui.slot_btn_login)
- // }
- }
后台C++代码
main.c
- /*********************************************************************
- * 主文件
- * (c)copyright 2014,jdh
- * All Right Reserved
- *新建日期:2014/1/27 by jdh
- *修改日期:2014/1/28 by jdh
- *修改日期:2014/2/4 by jdh
- *修改日期:2014/2/18 by jdh
- *修改日期:2014/2/27 by jdh
- *修改日期:2014/2/28 by jdh
- *修改日期:2014/3/1 by jdh
- *修改日期:2014/4/10 by jdh
- *修改日期:2014/5/4 by jdh
- **********************************************************************/
- #include "world.h"
- #include "main_gui.h"
- #include "login_gui.h"
- #include "light_gui.h"
- #include "heart_beat.h"
- #include "net.h"
- #include "data_sync_center.h"
- #include "set_ctrl_state.h"
- int main(int argc, char *argv[])
- {
- QGuiApplication app(argc, argv);
- //注册组件到QML
- qmlRegisterType<Login_Gui>("Login_Gui", 1, 0, "Login_Gui");
- QtQuick2ApplicationViewer viewer;
- viewer.setMainQmlFile(QStringLiteral("qml/SH_User/login.qml"));
- viewer.showExpanded();
- return app.exec();
- }
login_gui.h
- /*********************************************************************
- * 登陆界面模块头文件
- * (c)copyright 2014,jdh
- * All Right Reserved
- *新建日期:2014/1/29 by jdh
- *修改日期:2014/2/1 by jdh
- *修改日期:2014/2/18 by jdh
- *修改日期:2014/3/18 by jdh
- *修改日期:2014/5/4 by jdh
- *修改日期:2014/5/5 by jdh
- *修改日期:2014/5/13 by jdh
- **********************************************************************/
- #ifndef LOGIN_GUI_H
- #define LOGIN_GUI_H
- /*********************************************************************
- * 头文件
- **********************************************************************/
- #include "world.h"
- /*********************************************************************
- * 宏定义
- **********************************************************************/
- /*********************************************************************
- * 登录间隔
- *单位:ms
- **********************************************************************/
- #define INTERVAL_LOGIN 500
- /*********************************************************************
- * 最大登录次数
- **********************************************************************/
- #define NUM_LOGIN 5
- /*********************************************************************
- * 数据结构
- **********************************************************************/
- /*********************************************************************
- * 登录界面类
- **********************************************************************/
- class Login_Gui : public QObject
- {
- Q_OBJECT
- //属性:用户名
- Q_PROPERTY(QString user_id READ user_id WRITE set_user_id NOTIFY sig_user_id_changed)
- //属性:密码
- Q_PROPERTY(QString password READ password WRITE set_password NOTIFY sig_password_changed)
- //属性:记住密码标志
- Q_PROPERTY(bool flag_remember READ flag_remember
- WRITE set_flag_remember NOTIFY sig_flag_remember_changed)
- //属性:自动登录标志
- Q_PROPERTY(bool flag_auto READ flag_auto
- WRITE set_flag_auto NOTIFY sig_flag_auto_changed)
- public:
- /*********************************************************************
- * 函数
- **********************************************************************/
- /*********************************************************************
- * 初始化函数
- **********************************************************************/
- Login_Gui();
- /*********************************************************************
- * 解构函数
- **********************************************************************/
- ~Login_Gui();
- /*********************************************************************
- * 属性读取:用户号
- **********************************************************************/
- QString user_id();
- /*********************************************************************
- * 属性写入:用户号
- **********************************************************************/
- void set_user_id(QString str);
- /*********************************************************************
- * 属性读取:密码
- **********************************************************************/
- QString password();
- /*********************************************************************
- * 属性写入:密码
- **********************************************************************/
- void set_password(QString str);
- /*********************************************************************
- * 属性读取:记住密码标志
- **********************************************************************/
- bool flag_remember();
- /*********************************************************************
- * 属性写入:记住密码标志
- **********************************************************************/
- void set_flag_remember(bool flag);
- /*********************************************************************
- * 属性读取:自动登陆标志
- **********************************************************************/
- bool flag_auto();
- /*********************************************************************
- * 属性写入:自动登陆标志
- **********************************************************************/
- void set_flag_auto(bool flag);
- signals:
- /*********************************************************************
- * 属性改变信号:用户号
- **********************************************************************/
- void sig_user_id_changed();
- /*********************************************************************
- * 属性改变信号:密码
- **********************************************************************/
- void sig_password_changed();
- /*********************************************************************
- * 属性改变信号:记住密码标志
- **********************************************************************/
- void sig_flag_remember_changed();
- /*********************************************************************
- * 属性改变信号:自动登陆标志
- **********************************************************************/
- void sig_flag_auto_changed();
- /*********************************************************************
- * 信号:登陆结果
- *参数:result:0:成功
- * 1:无此用户名
- * 2:密码错误
- * 3:达到登陆的最大次数
- **********************************************************************/
- void sig_login_result(int result);
- /*********************************************************************
- * 发送网络帧
- *参数:id:用户名
- * password:密码
- * cmd:帧命令
- * index:发送序列号
- * frame:发送的报文
- **********************************************************************/
- void sig_net_tx_frame_with_id(uint32_t id,uint32_t password,int cmd,uint16_t index,QByteArray frame);
- public slots:
- /*********************************************************************
- * 槽函数:登陆请求
- **********************************************************************/
- void slot_login_req();
- /*********************************************************************
- * 槽函数:登陆响应
- *参数:data:接收的数据
- **********************************************************************/
- void slot_login_ack(QByteArray data);
- private slots:
- /*********************************************************************
- * 槽函数:心跳滴答函数
- *说明:1滴答触发1次
- **********************************************************************/
- void slot_tick();
- private:
- /*********************************************************************
- * 变量
- **********************************************************************/
- /*********************************************************************
- * 属性:用户号
- **********************************************************************/
- QString _user_id;
- /*********************************************************************
- * 属性:密码
- **********************************************************************/
- QString _password;
- /*********************************************************************
- * 属性:记住密码标志
- **********************************************************************/
- bool _flag_remember;
- /*********************************************************************
- * 属性:自动登录标志
- **********************************************************************/
- bool _flag_auto;
- /*********************************************************************
- * 滴答定时器
- **********************************************************************/
- QTimer *timer;
- /*********************************************************************
- * 登录计数器
- **********************************************************************/
- int Login_Counter;
- };
- #endif // LOGIN_GUI_H
login_gui.c
- /*********************************************************************
- * 登陆界面模块主文件
- * (c)copyright 2014,jdh
- * All Right Reserved
- *新建日期:2014/1/29 by jdh
- *修改日期:2014/2/1 by jdh
- *修改日期:2014/2/17 by jdh
- *修改日期:2014/2/18 by jdh
- *修改日期:2014/2/16 by jdh
- *修改日期:2014/5/4 by jdh
- *修改日期:2014/5/5 by jdh
- *修改日期:2014/5/13 by jdh
- **********************************************************************/
- /*********************************************************************
- * 头文件
- **********************************************************************/
- #include "login_gui.h"
- /*********************************************************************
- * 函数
- **********************************************************************/
- /*********************************************************************
- * 初始化函数
- **********************************************************************/
- Login_Gui::Login_Gui()
- {
- //初始化变量
- Login_Counter = 0;
- //滴答初始化
- timer = new QTimer(this);
- //绑定信号槽
- connect(timer, SIGNAL (timeout()), this , SLOT(slot_tick()));
- QFile file_cfg("cfg.txt");
- QByteArray arr;
- bool ok;
- int flag_remember = 0;
- int flag_auto_login = 0;
- int id = 0;
- int password = 0;
- QString str;
- int i = 0;
- int j = 0;
- //属性初始化
- _user_id = "";
- _password = "";
- _flag_remember = false;
- _flag_auto = false;
- //判断文件是否存在
- if (!file_cfg.exists())
- {
- file_cfg.close();
- }
- else
- {
- //文件存在
- file_cfg.open(QIODevice::ReadOnly);
- //读取文件
- do
- {
- str.clear();
- arr = file_cfg.readLine();
- for (i = 0;i < arr.count();i++)
- {
- if ((arr.at(i) >= '0' && arr.at(i) <= '9') ||
- (arr.at(i) >= 'a' && arr.at(i) <= 'f') ||
- arr.at(i) == 'x')
- {
- str[j++] = arr.at(i);
- }
- }
- flag_remember = str.toInt(&ok,16);
- if (!ok)
- {
- break;
- }
- str.clear();
- arr = file_cfg.readLine();
- for (i = 0;i < arr.count();i++)
- {
- if ((arr.at(i) >= '0' && arr.at(i) <= '9') ||
- (arr.at(i) >= 'a' && arr.at(i) <= 'f') ||
- arr.at(i) == 'x')
- {
- str[j++] = arr.at(i);
- }
- }
- flag_auto_login = str.toInt(&ok,16);
- if (!ok)
- {
- break;
- }
- str.clear();
- arr = file_cfg.readLine();
- for (i = 0;i < arr.count();i++)
- {
- if ((arr.at(i) >= '0' && arr.at(i) <= '9') ||
- (arr.at(i) >= 'a' && arr.at(i) <= 'f') ||
- arr.at(i) == 'x')
- {
- str[j++] = arr.at(i);
- }
- }
- id = str.toInt(&ok,16);
- if (!ok)
- {
- break;
- }
- str.clear();
- arr = file_cfg.readLine();
- for (i = 0;i < arr.count();i++)
- {
- if ((arr.at(i) >= '0' && arr.at(i) <= '9') ||
- (arr.at(i) >= 'a' && arr.at(i) <= 'f') ||
- arr.at(i) == 'x')
- {
- str[j++] = arr.at(i);
- }
- }
- password = str.toInt(&ok,16);
- if (!ok)
- {
- break;
- }
- //判断是否记住密码
- if (flag_remember == VALID_FLAG)
- {
- _user_id = QString::number(id,10);
- _password = QString::number(password,10);
- _flag_remember = true;
- //判断是否自动登录
- if (flag_auto_login == VALID_FLAG)
- {
- _flag_auto = true;
- slot_login_req();
- }
- }
- } while (0);
- file_cfg.close();
- }
- }
- /*********************************************************************
- * 解构函数
- **********************************************************************/
- Login_Gui::~Login_Gui()
- {
- }
- /*********************************************************************
- * 属性读取:用户号
- **********************************************************************/
- QString Login_Gui::user_id()
- {
- return _user_id;
- }
- /*********************************************************************
- * 属性写入:用户号
- **********************************************************************/
- void Login_Gui::set_user_id(QString str)
- {
- if (_user_id != str)
- {
- _user_id = str;
- emit sig_user_id_changed();
- }
- }
- /*********************************************************************
- * 属性读取:密码
- **********************************************************************/
- QString Login_Gui::password()
- {
- return _password;
- }
- /*********************************************************************
- * 属性写入:密码
- **********************************************************************/
- void Login_Gui::set_password(QString str)
- {
- if (_password != str)
- {
- _password = str;
- emit sig_password_changed();
- }
- }
- /*********************************************************************
- * 属性读取:记住密码标志
- **********************************************************************/
- bool Login_Gui::flag_remember()
- {
- return _flag_remember;
- }
- /*********************************************************************
- * 属性写入:记住密码标志
- **********************************************************************/
- void Login_Gui::set_flag_remember(bool flag)
- {
- if (_flag_remember != flag)
- {
- _flag_remember = flag;
- emit sig_flag_remember_changed();
- }
- }
- /*********************************************************************
- * 属性读取:自动登陆标志
- **********************************************************************/
- bool Login_Gui::flag_auto()
- {
- return _flag_auto;
- }
- /*********************************************************************
- * 属性写入:自动登陆标志
- **********************************************************************/
- void Login_Gui::set_flag_auto(bool flag)
- {
- if (_flag_auto != flag)
- {
- _flag_auto = flag;
- emit sig_flag_auto_changed();
- }
- }
- /*********************************************************************
- * 槽函数:登陆请求
- **********************************************************************/
- void Login_Gui::slot_login_req()
- {
- //初始化计数器
- Login_Counter = 0;
- //开始尝试登陆
- timer->start(INTERVAL_LOGIN);
- slot_tick();
- }
- /*********************************************************************
- * 槽函数:登陆响应
- *参数:data:接收的数据
- **********************************************************************/
- void Login_Gui::slot_login_ack(QByteArray data)
- {
- uint32_t id = 0;
- uint32_t password = 0;
- int flag_remember = 0;
- int flag_auto_login = 0;
- uint8_t result = 0;
- bool ok;
- #ifdef DEBUG
- qDebug() << "接收帧:尝试登陆" << (uint8_t)data[0] << (uint8_t)data[1] << (uint8_t)data[2];
- #endif
- //清除计数器
- Login_Counter = 0;
- //停止登录尝试
- timer->stop();
- //判断用户号和密码是否匹配
- id = ((uint8_t)data[6] << 24) +
- ((uint8_t)data[7] << 16) +
- ((uint8_t)data[8] << 8) +
- (uint8_t)data[9];
- password = ((uint8_t)data[10] << 24) +
- ((uint8_t)data[11] << 16) +
- ((uint8_t)data[12] << 8) +
- (uint8_t)data[13];
- //登陆结果
- result = (uint8_t)data[LEN_FRAME_HEAD];
- //判断登陆结果
- switch (result)
- {
- //登陆成功
- case 0:
- {
- //判断用户名和密码是否正确
- if (id == (uint32_t)_user_id.toInt(&ok) && password == (uint32_t)_password.toInt(&ok))
- {
- //发送登陆成功信号
- emit sig_login_result(0);
- #ifdef DEBUG
- qDebug() << "登陆成功" << "用户号" << _user_id << "密码" << _password;
- #endif
- //判断是否勾选记住密码以及自动登录
- if (_flag_remember)
- {
- flag_remember = VALID_FLAG;
- }
- if (_flag_auto)
- {
- flag_auto_login = VALID_FLAG;
- }
- //将用户名密码保存
- QFile file_cfg("cfg.txt");
- file_cfg.open(QIODevice::WriteOnly);
- QTextStream out(&file_cfg);
- out << QString::number(flag_remember,16) << " "
- << QString::number(flag_auto_login,16) << " "
- << _user_id << " "
- << _password << " ";
- file_cfg.close();
- }
- break;
- }
- //无此用户名
- case 1:
- {
- #ifdef DEBUG
- qDebug() << "登陆失败" << "用户号不存在";
- #endif
- //发送登录失败信号
- emit sig_login_result(1);
- break;
- }
- //密码错误
- case 2:
- {
- #ifdef DEBUG
- qDebug() << "登陆失败" << "密码错误";
- #endif
- //发送登录失败信号
- emit sig_login_result(2);
- break;
- }
- }
- }
- /*********************************************************************
- * 槽函数:心跳滴答函数
- *说明:1滴答触发1次
- **********************************************************************/
- void Login_Gui::slot_tick()
- {
- QByteArray frame;
- bool ok;
- //登录计数器
- Login_Counter++;
- if (Login_Counter > NUM_LOGIN)
- {
- #ifdef DEBUG
- qDebug() << "登录失败" << "达到最大尝试登陆次数:" << NUM_LOGIN;
- #endif
- //清除计数器
- Login_Counter = 0;
- //停止登陆尝试
- timer->stop();
- //发送登陆失败信号
- emit sig_login_result(3);
- return;
- }
- //发送登陆请求
- //报文
- frame.clear();
- //发送网络帧
- #ifdef DEBUG
- qDebug() << "发送帧:发送登陆请求";
- #endif
- emit sig_net_tx_frame_with_id((uint32_t)_user_id.toInt(&ok),(uint32_t)_password.toInt(&ok),
- CMD_USER_LOGIN_REQUEST,0,frame);
- }
http://blog.csdn.net/jdh99/article/details/25774797