QML与C++交互:登陆界面设计

本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.



环境:

主机:WIN7

开发环境:Qt5.2.1

说明:

QML设计前台界面,C++后台负责逻辑

效果图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamRoOTk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamRoOTk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

源码:



前台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
width: 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;
//无此username
case 1:
message.text = "登陆失败:无此username"
message.opacity = 1
break;
//password错误
case 2:
message.text = "登陆失败:password错误"
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
width: 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
width: login.width; height: login.height * 0.1
anchors.top: top_bar.bottom
} //登陆框
Rectangle
{
id: rect1
width: 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
{
width: rect1.width * 0.05; height: rect1.height
} Column
{
spacing: rect1.height * 0.025 Item
{
width: rect1.width * 0.8; height: rect1.height * 0.05
} LineInput
{
id: txt_user_id
width: 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
width: 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: "请输入password"
text:login_gui.password
} Row
{
spacing: rect1.width * 0.1
Button
{
id: btn_login
width: 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
width: 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
width: rect1.width * 0.35; height: rect1.height * 0.2
//anchors { left: rect1.left; top: rect1.bottom }
caption: "记住password"
selected: login_gui.flag_remember
} CheckBox
{
id: check2
width: 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()
{
//推断username是否有效
if (txt_user_id.text == "")
{
message.text = "请输入username"
message.opacity = 1
return
} //推断password是否有效
if (txt_password.text == "")
{
message.text = "请输入password"
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 //属性:username
Q_PROPERTY(QString user_id READ user_id WRITE set_user_id NOTIFY sig_user_id_changed)
//属性:password
Q_PROPERTY(QString password READ password WRITE set_password NOTIFY sig_password_changed)
//属性:记住password标志
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); /*********************************************************************
* 属性读取:password
**********************************************************************/ QString password(); /*********************************************************************
* 属性写入:password
**********************************************************************/ void set_password(QString str); /*********************************************************************
* 属性读取:记住password标志
**********************************************************************/ bool flag_remember(); /*********************************************************************
* 属性写入:记住password标志
**********************************************************************/ void set_flag_remember(bool flag); /*********************************************************************
* 属性读取:自己主动登陆标志
**********************************************************************/ bool flag_auto(); /*********************************************************************
* 属性写入:自己主动登陆标志
**********************************************************************/ void set_flag_auto(bool flag); signals: /*********************************************************************
* 属性改变信号:用户号
**********************************************************************/ void sig_user_id_changed(); /*********************************************************************
* 属性改变信号:password
**********************************************************************/ void sig_password_changed(); /*********************************************************************
* 属性改变信号:记住password标志
**********************************************************************/ void sig_flag_remember_changed(); /*********************************************************************
* 属性改变信号:自己主动登陆标志
**********************************************************************/ void sig_flag_auto_changed(); /*********************************************************************
* 信号:登陆结果
*參数:result:0:成功
* 1:无此username
* 2:password错误
* 3:达到登陆的最大次数
**********************************************************************/ void sig_login_result(int result); /*********************************************************************
* 发送网络帧
*參数:id:username
* password: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; /*********************************************************************
* 属性:password
**********************************************************************/ QString _password; /*********************************************************************
* 属性:记住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:
{
//推断username与password是否正确
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;
} //将username密码保存
QFile file_cfg("cfg.txt");
file_cfg.open(QIODevice::WriteOnly);
QTextStream out(&file_cfg);
out << QString::number(flag_remember,16) << "\r\n" \
<< QString::number(flag_auto_login,16) << "\r\n" \
<< _user_id << "\r\n" \
<< _password << "\r\n";
file_cfg.close();
} break;
}
//无此username
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);
}

最新文章

  1. 执行git push出现&quot;Everything up-to-date&quot;
  2. 【Java EE 学习 32 上】【JQuery】【选择器】
  3. Knockout.js是什么?
  4. hdu 3506 Monkey Party 区间dp + 四边形不等式优化
  5. Java+MySql图片数据保存与读取的具体实例
  6. [转]Java 泛型: 什么是PECS(Producer Extends, Consumer Super)
  7. Mediator
  8. 模拟实现STL中的list
  9. c语言下的通用数据库接口(之sqlite消化,模拟c#,java的反射)
  10. highcharts 多数据+切换
  11. Palindrome(poj3974)(manacher算法)
  12. LRU 缓冲池 (不考虑多线程)
  13. Python中的引用的使用注意
  14. 阿里巴巴开源项目:分布式数据库同步系统otter(解决中美异地机房) - agapple - ITeye技术网站
  15. weekend110(Hadoop)的 第六天笔记
  16. Json.Net学习笔记(十) 保持对象引用
  17. Android UI 使用HTML布局(直接打开server网页)
  18. perl的INC
  19. java CountDownLatch 使用介绍
  20. MySql基础总结

热门文章

  1. Java IO(一)--File类
  2. Spring Cloud练习1
  3. 01Hibernate
  4. 04Struts2的配置文件
  5. Leetcode 54:Spiral Matrix 螺旋矩阵
  6. js获取当前位置
  7. Python:用户自定义异常
  8. uva 10596 - Morning Walk
  9. python 开发搭建目录规范
  10. (转载)Catalan数——卡特兰数