在网上不是很好找到登录界面转主窗口的,决定自己写一个,研究了一下main函数,发现主要问题是处理好main函数中a.exec()。
除了完成上述操作外,还增加了注册账号、找回密码、记住密码的操作。
主要目标
- 软件界面
- 注册账号
- 登录跳转
- 找回密码
- 自动登录
软件界面
-
登陆界面
在登录界面中,除输入栏外,还增加了记住密码、找回密码、自动登录、注册账号、设置等(自动登录与设置没有写槽函数)。
-
注册账号界面
功能如图所示(不要在意窗口标题,忘了改了,而且今天又不想改了了)
-
找回密码界面
功能如图所示(emmm…不要在意窗口标题)
注意: 在给Widget添加背景时,直接在ui的styleSheet修改是无效的,需要重写 void paintEvent(QPaintEvent)*,还要添加资源到项目。
void QAnyClass::paintEvent(QPaintEvent*)
{
QPainter paint_win(this);
QPixmap map_win;
map_win.load(":/fig_sign/src_fig/evening-55067.png");
paint_win.drawPixmap(0,0,this->width(),this->height(),map_win);
}
注册账号
注册账号需要点击登录窗口的“注册账号”选项,来弹出注册账号窗口(除此之外,登录、修改密码等都是通过调用检查文件userInfo.csv)点击注册窗口确认按钮,触发对应槽函数。类名为:bfSign(登录前夜)
bfsign.h
#ifndef BFSIGN_H
#define BFSIGN_H
#include <QWidget>
namespace Ui {
class bfSign;
}
class bfSign : public QWidget
{
Q_OBJECT
public:
explicit bfSign(QWidget *parent = nullptr);
~bfSign();
void paintEvent(QPaintEvent*);
public slots:
void register_check();
private:
Ui::bfSign *ui;
};
#endif // BFSIGN_H
bfsign.cpp
#include "bfsign.h"
#include "ui_bfsign.h"
#include <QPainter>
#include <QFile>
#include <QTextStream>
bfSign::bfSign(QWidget *parent) :
QWidget(parent),
ui(new Ui::bfSign)
{
ui->setupUi(this);
connect(ui->toolButton_8,SIGNAL(clicked()),this,SLOT(close()));
connect(ui->toolButton_7,SIGNAL(clicked()),this,SLOT(register_check()));
}
bfSign::~bfSign()
{
delete ui;
}
void bfSign::paintEvent(QPaintEvent*)
{
QPainter paint_win(this);
QPixmap map_win;
map_win.load(":/fig_sign/src_fig/evening-55067.png");
paint_win.drawPixmap(0,0,this->width(),this->height(),map_win);
}
void bfSign::register_check()
{
QString name=ui->lineEdit->text();
QString key=ui->lineEdit_2->text();
QString akey=ui->lineEdit_3->text();
QString pquestion=ui->lineEdit_4->text();
QString answare=ui->lineEdit_5->text();
QFile file("userInfo.csv");
file.open(QIODevice::ReadOnly);
QTextStream in(&file);
QStringList tempOption;
bool user_repeat=false;
if(name==""||key==""||akey==""||pquestion==""||answare=="")
ui->lineEdit_6->setText("请补全信息!");
else
{
while (!in.atEnd())
{
tempOption=in.readLine().split(",");
if(name==tempOption[0])
{
ui->lineEdit_6->setText("账户已存在!");
{
user_repeat=true;
break;
}
}
}
file.close();
if(!user_repeat)
{
if(key!=akey)
ui->lineEdit_6->setText("二次密码错误!");
else
{
QFile file("userInfo.csv");
file.open(QIODevice::Append);
file.write((name+","+key+","+pquestion+","+answare+","+"\r\n").toLocal8Bit());
ui->lineEdit_6->setText("注册成功");
}
}
}
}
登录跳转
这里就涉及到怎样从登录窗口跳到主窗口。
输入账号密码后,点击登录按钮,如果密码正确应该关闭登录窗口打开主窗口。
观察主函数**a.exec()**是消息循环机制,看一下官方说明:
Enters the main event loop and waits until exit() is called, then returns the value that was set to exit() (which is 0 if exit() is called via quit()).
意思是当前窗口关闭了就会结束a.exec(),那么只要在主函数中a.exec()结束后,直接调出主窗口就行了,而且要知道 return a.exec()与a.exec(); return0;所以吧return a.exec()拆开就行了,见代码:
main.cpp
#include "widget.h" //登录窗口
#include "mywidget.h" //主窗口
#include "parameter.h" //字节写的参数头文件
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
a.exec(); //等待登录窗口关闭
if(success_pass) //extern bool success_pass标志为true时标志着密码正确
{
success_pass=false;
myWidget mW; //创建主窗口
mW.show();
a.exec();
}
return 0;
}
登录窗口程序
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "bfsign.h"
#include "rfaccount.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void paintEvent(QPaintEvent*);
private:
Ui::Widget *ui;
public slots:
void sign_in();//登录
signals:
void fill_bg();
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QIcon>
#include <QPainter>
#include <QFileDialog>
#include <QFile>
#include <QTextCodec>
#include <QDebug>
#include <QStringList>
bool success_pass = false;
bool cBox_state=false;
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
setWindowIcon(QIcon(":/fig_sign/src_fig/Huawei MateBook Pro 2019_wallpaper_05.png"));
setWindowTitle("LISTEN");
QFile file("userInfo.txt");
file.open(QIODevice::ReadOnly);
QTextStream in(&file);
if(!in.atEnd())
{
ui->lineEdit->setText(in.readLine());
ui->lineEdit_2->setText(in.readLine());
}
file.close();
QString s_name;
QString s_key;
file.write((s_name+"\r\n").toLocal8Bit());
file.write((s_key+"\r\n").toLocal8Bit());
file.close();
connect(ui->toolButton_2,&QToolButton::clicked,this,[](){
rfAccount* rf=new rfAccount;
rf->show();
});
connect(ui->toolButton,&QToolButton::clicked,this,[](){
bfSign* bf1=new bfSign;
bf1->show();
});
connect(ui->toolButton_3,SIGNAL(clicked()),this,SLOT(sign_in()));
connect(ui->checkBox,&QCheckBox::stateChanged,this,[](){
if(!cBox_state)
cBox_state=true;
else
cBox_state=false;
});
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent*)
{
QPainter paint_win(this);
QPixmap map_win;
map_win.load(":/fig_sign/src_fig/3_copy1.png");
paint_win.drawPixmap(0,0,this->width(),this->height(),map_win);
}
void Widget::sign_in()
{
QString s_name = ui->lineEdit->text();
QString s_key = ui->lineEdit_2->text();
QFile file("userInfo.csv");
file.open(QIODevice::ReadOnly);
QTextStream in(&file);
QStringList tempOption;
while (!in.atEnd())
{
tempOption=in.readLine().split(",");
if(s_name==tempOption[0])
{
if(s_key==tempOption[1])
success_pass = true;
break;
}
}
file.close();
if(success_pass)
{
if(cBox_state)
{
QString s_name = ui->lineEdit->text();
QString s_key = ui->lineEdit_2->text();
QFile file("userInfo.txt");
file.open(QIODevice::WriteOnly);
file.write((s_name+"\r\n").toLocal8Bit());
file.write((s_key+"\r\n").toLocal8Bit());
file.close();
}
this->close();//触发main函数中对应a.exec()结束消息循环,并关闭登陆窗,转到主窗口
}
else
ui->lineEdit_3->setText("账户或密码错误!");
}
找回密码
相信大家都有忘记密码的苦恼,没有错,正如前面找回密码窗口所见,你设置了密保问题,通过回答密保就可以修改密码了。类名:rfAccount(再次探寻)
rfaccount.h
#ifndef RFACCOUNT_H
#define RFACCOUNT_H
#include <QWidget>
namespace Ui {
class rfAccount;
}
class rfAccount : public QWidget
{
Q_OBJECT
public:
explicit rfAccount(QWidget *parent = nullptr);
~rfAccount();
void paintEvent(QPaintEvent*);
public slots:
void check_user();
void get_user();
void accheck_user();
private:
Ui::rfAccount *ui;
};
#endif // RFACCOUNT_H
rfaccount.cpp
#include "rfaccount.h"
#include "ui_rfaccount.h"
#include <QPainter>
#include <QString>
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include <vector>
rfAccount::rfAccount(QWidget *parent) :
QWidget(parent),
ui(new Ui::rfAccount)
{
ui->setupUi(this);
ui->toolButton_7->hide();//隐藏按钮,输入正确用户名后显示
ui->toolButton_8->hide();隐藏按钮,输入正确密保答案后显示
connect(ui->toolButton,SIGNAL(clicked()),this,SLOT(check_user()));
connect(ui->toolButton_7,SIGNAL(clicked()),this,SLOT(accheck_user()));
connect(ui->toolButton_8,SIGNAL(clicked()),this,SLOT(get_user()));
}
rfAccount::~rfAccount()
{
delete ui;
}
void rfAccount::paintEvent(QPaintEvent*)
{
QPainter paint_win(this);
QPixmap map_win;
map_win.load(":/fig_sign/src_fig/evening-55067.png");
paint_win.drawPixmap(0,0,this->width(),this->height(),map_win);
}
void rfAccount::check_user()
{
QString name = ui->lineEdit->text();
QFile file("userInfo.csv");
file.open(QIODevice::ReadOnly);
QTextStream in(&file);
QStringList tempOption;
bool user_been=false;
while (!in.atEnd())
{
tempOption=in.readLine().split(",");
if(name==tempOption[0])
{
ui->lineEdit_2->setText(tempOption[2]);
ui->toolButton_7->show();
user_been=true;
break;
}
}
file.close();
if(!user_been)
ui->lineEdit_6->setText("账户不存在!");
}
void rfAccount::accheck_user()
{
QString name = ui->lineEdit->text();
QString answer = ui->lineEdit_3->text();
QFile file1("userInfo.csv");
file1.open(QIODevice::ReadOnly);
QTextStream in1(&file1);
QStringList tempOption1;
bool key_right=false;
while (!in1.atEnd())
{
tempOption1=in1.readLine().split(",");
if(name==tempOption1[0])
{
ui->toolButton_8->show();
key_right=true;
break;
}
}
file1.close();
if(key_right)
{
ui->lineEdit_6->setText("回答正确!");
key_right=false;
}
else
ui->lineEdit_6->setText("请输入新密码");
}
void rfAccount::get_user()
{
QString name = ui->lineEdit->text();
QString key = ui->lineEdit_4->text();
QString akey = ui->lineEdit_5->text();
if(key!=akey)
ui->lineEdit_6->setText("密码不一致!");
else
{
QFile file1("userInfo.csv");
file1.open(QIODevice::ReadWrite);
QTextStream in1(&file1);
QStringList tempOption1;
bool modify_su=false;
tempOption1=in1.readAll().split("\n");
file1.close();
QStringList temp;
QString tran_temp;
int count_h=tempOption1.count();
for(int i=0;i!=count_h;i++)
{
temp=tempOption1.at(i).split(",");
if(temp[0]==name)
{
tempOption1[i]=name+","+key+","+temp[2]+","+temp[3];
ui->lineEdit_6->setText("修改成功");
modify_su=true;
}
}
if(modify_su)
{
file1.open(QIODevice::WriteOnly);
for(int i=0;i!=count_h;i++)
{
file1.write((tempOption1[i]+"\r\n").toLocal8Bit());
}
file1.close();
}
else
ui->lineEdit_6->setText("修改失败");
}
}
记住密码
你还在为重复输入账号密码而苦恼吗?贴心的我为你准备了记住密码功能,让你在下次登陆时一键登录!(在创建登录窗口类的析构函数中,查userInfo.txt,获取用户信息)
emmm… 登录窗口widget.cpp好像展示过了,不过为了展现我有这个功能,我还是要把它单独拎出来!
//h文件构建类时访问
QFile file("userInfo.txt");
file.open(QIODevice::ReadOnly);
QTextStream in(&file);
if(!in.atEnd())
{
ui->lineEdit->setText(in.readLine());
ui->lineEdit_2->setText(in.readLine());
}
file.close();
//cpp文件中修改
QString s_name = ui->lineEdit->text();
QString s_key = ui->lineEdit_2->text();
QFile file("userInfo.txt");
file.open(QIODevice::WriteOnly);
file.write((s_name+"\r\n").toLocal8Bit());
file.write((s_key+"\r\n").toLocal8Bit());
file.close();
注意:打开文件后一定要close()一下。
最后
后面我打算在登陆主窗口后,添加消息、语音、视频、文件收发功能,还要为文件使用ARQ协议,确保文件成功发送,当然了,下次更新可能要一两周了,更久也说不定。
作为qt的初级使用者,代码必然会有冗余的地方,还请大佬们不吝指教!