您的位置:首页 > 编程语言 > C语言/C++

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

2015-05-14 17:21 465 查看
环境:

主机:WIN7

开发环境:Qt5.2.1

说明:

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

效果图:









源代码:

前台qml文件

login.qml

[javascript] view
plaincopy





/*********************************************************************

* 登陆界面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;

//无此用户名

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

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: "请输入密码"

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: "记住密码"

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()

{

//判断用户名是否有效

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

[cpp] view
plaincopy





/*********************************************************************

* 主文件

* (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

[cpp] view
plaincopy





/*********************************************************************

* 登陆界面模块头文件

* (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

[cpp] view
plaincopy





/*********************************************************************

* 登陆界面模块主文件

* (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) << "\r\n" \

<< QString::number(flag_auto_login,16) << "\r\n" \

<< _user_id << "\r\n" \

<< _password << "\r\n";

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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: