【QT】为自己的QT程序添加一个登录界面

【QT】为自己的QT程序添加一个登录界面

接了一个私活,做完后非要加一个这个功能,自己尝试着做了一下,模块都是独立的,不会和主界面有多少关联,主界面也基本没有改动。总体上还是属于自己瞎琢磨的一个方法,可能不是非常的专业,不过总体上就是简单快捷。

需要加的这个登录系统并没有注册功能,等同于给软件加了一个密码,密码写在源码里。

这里写目录标题

1.创建一个新的ui界面2.打开ui设计页面,拖动控件,布置界面。3.如何通过登录界面登录主界面4.设置登录界面的账号和密码5.实现记住账号和记住密码功能6. 防止主窗口和登录窗口同时打开7.最终完整代码:8. 源码分享9. 答疑

1.创建一个新的ui界面

右击项目目录,选择Add New创建新文件:

空白界面即可,我们可以自己加控件

设置名称,然后即可。

2.打开ui设计页面,拖动控件,布置界面。

然后设计如下界面:

总共拖到的控件如下: 至于页面布局,可以在ui设计界面手动设置,或者可以在logwidget.cpp文件下代码设置,根据自己习惯定:

void LogWidget::form_init()

{

// 文件标题名

ui->label_title->setGeometry(120,25,160,25);

ui->groupBox->setGeometry(50,60,300,125);

ui->label_name->setGeometry(25,25,100,25);

ui->edit_name->setGeometry(125,25,150,25);

ui->label_pw->setGeometry(25,75,100,25);

ui->edit_pw->setGeometry(125,75,150,25);

ui->check_name->setGeometry(85,200,100,25);

ui->check_pw->setGeometry(215,200,100,25);

ui->btn_log->setGeometry(50,235,120,30);

ui->btn_clear->setGeometry(230,235,120,30);

//调整字体大小

QFont font;

font.setPointSize(16); //实际上是16的字号,但设成16却不行

font.setFamily(("wenquanyi"));

font.setBold(false);

ui->label_title->setFont(font);

font.setPointSize(12);

ui->label_name->setFont(font);

ui->label_pw->setFont(font);

}

3.如何通过登录界面登录主界面

其实前两个部分都是无关紧要的,核心部分从这里开始。 我们之前打开主界面的主函数代码一般都是:

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

MainWindow w;

w.show();

return a.exec();

}

但我们现在要做出的效果是,先弹出登录界面,然后根据登录界面的按钮进入主界面; 我的方法是: 1.在MainWindow 对象初始化时创建登录界面对象LogWidget,并调用LogWidget对象的show方法。 2.主函数中并不调用MainWindow 对象的show()函数,而是通过信号槽机制,通过LogWidget的登录按钮发出信号,然后调用到MainWindow的show方法 3.同样通过信号槽机制,LogWidget的登录按钮发出信号之后,调用LogWidget的close()函数,实现登录主界面后的登录界面关闭。

logwidget.h

namespace Ui {

class LogWidget;

}

class LogWidget : public QWidget

{

Q_OBJECT

public:

explicit LogWidget(QWidget *parent = nullptr);

~LogWidget();

signals:

void login(); //登录主界面信号

void close_window(); //关闭登录界面信号

public slots:

void btn_clear_clicked(); //重置按钮按下后触发的事件

void btn_log_clicked(); //登录按钮按下后触发的事件

private:

Ui::LogWidget *ui;

};

logwidget.cpp

LogWidget::LogWidget(QWidget *parent) :

QWidget(parent),

ui(new Ui::LogWidget)

{

ui->setupUi(this);

// connect 3个信号槽

// 触发重置按钮的信号槽连接

connect(ui->btn_clear,SIGNAL(clicked()),this,SLOT(btn_clear_clicked()));

// 触发登录按钮的信号槽连接

connect(ui->btn_log,SIGNAL(clicked()),this,SLOT(btn_log_clicked()));

// 发出信号后关闭登录窗口的信号槽连接

connect(this,SIGNAL(close_window()),this,SLOT(close()));

}

// 清理输入栏

void LogWidget::btn_clear_clicked()

{

ui->edit_pw->clear();

ui->edit_name->clear();

}

// 登录按钮触发事件

void LogWidget::btn_log_clicked()

{

// 发出登录信号

emit(login());

// 发出关闭窗口信号

emit(close_window());

}

mainwindow.h

QT_BEGIN_NAMESPACE

namespace Ui { class MainWindow; }

QT_END_NAMESPACE

class MainWindow : public QMainWindow

{

Q_OBJECT

public:

MainWindow(QWidget *parent = nullptr);

~MainWindow();

private:

Ui::MainWindow *ui;

// 登录界面类的对象作为指针

LogWidget * m_log;

};

#endif // MAINWINDOW_H

mainwindow.cpp

MainWindow::MainWindow(QWidget *parent)

: QMainWindow(parent)

, ui(new Ui::MainWindow)

{

ui->setupUi(this);

// 通过指针创建登录界面类的对象

m_log = new LogWidget;

// 调用登录窗口的show()函数显示登录界面

m_log->show();

// 建立信号槽,到接收到登录界面发来的login()信号后,调用主窗口的show()函数。

connect(m_log,SIGNAL(login()),this,SLOT(show()));

}

4.设置登录界面的账号和密码

这个思路根据实际需求来定,目前我的情况,只是把这些在代码里写死即可。然后获取输入框的数据,和内置密码进行比对。

其实更常规的做法,应该时设置一个账号密码的数据库,简单一点就是设置一个json文件或者txt文件,采用文件读取的方式。

namespace Ui {

class LogWidget;

}

class LogWidget : public QWidget

{

Q_OBJECT

public:

explicit LogWidget(QWidget *parent = nullptr);

~LogWidget();

signals:

void login(); //登录主界面信号

void close_window(); //关闭登录界面信号

public slots:

void btn_clear_clicked(); //重置按钮按下后触发的事件

void btn_log_clicked(); //登录按钮按下后触发的事件

private:

Ui::LogWidget *ui;

QString m_username; // 自己设定的账号

QString m_password; // 自己设定的密码

};

logwidget.cpp 修改登录按钮触发事件btn_log_clicked()

LogWidget::LogWidget(QWidget *parent) :

QWidget(parent),

ui(new Ui::LogWidget)

{

ui->setupUi(this);

// connect

// 触发重置按钮的信号槽连接

connect(ui->btn_clear,SIGNAL(clicked()),this,SLOT(btn_clear_clicked()));

// 触发登录按钮的信号槽连接

connect(ui->btn_log,SIGNAL(clicked()),this,SLOT(btn_log_clicked()));

// 发出信号后关闭登录窗口的信号槽连接

connect(this,SIGNAL(close_window()),this,SLOT(close()));

ui->edit_pw->setEchoMode(QLineEdit::Password);//输入的时候就显示圆点

m_username = "wuyongwen";

m_password = "wuyongwen";

}

void LogWidget::btn_log_clicked()

{

// 从输入框获取账号

QString name = ui->edit_name->text();

// 从输入框获取密码

QString password = ui->edit_pw->text();

//账号和密码匹配正确

if (name == m_username && password == m_password)

{

emit(login());

emit(close_window());

}

else // 账号或密码错误

QMessageBox::information(this, "Warning","Username or Password is wrong !");

}

5.实现记住账号和记住密码功能

这种功能需要我们把一部分信息存储为配置文件,程序在初始化时进行读取,然后执行对应设置。

基本思路: 1.创建一个json文件 2.登录界面初始化时会读取json文件 3.根据json文件数据觉得是否自动填入账号和密码,并在多选框内自动打勾 4.每次触发登录按钮,假如成功登录,就再一次根据多选框的打勾情况,重新写入json文件。

(在本显示代码中,设置的json存取路径为当前的项目包路径(QApplication::applicationDirPath()+“/config.json”),可以自行替换json文件的路径)

json文件设置 SAVE_NAME对应键值0表示不保存账号,1表示保存账号; SAVE_PASSWORD对应键值0表示不保存密码,1表示保存密码;

logwidget.h

#include

#include

#include

#include

#include

#include

#include

namespace Ui {

class LogWidget;

}

class LogWidget : public QWidget

{

Q_OBJECT

public:

explicit LogWidget(QWidget *parent = nullptr);

~LogWidget();

void read_json(); //读json

void write_json();//写json

void message_init(QString flag1,QString flag2);//根据json内容决定是否填充输入框

signals:

void login(); //登录主界面信号

void close_window(); //关闭登录界面信号

public slots:

void btn_clear_clicked(); //重置按钮按下后触发的事件

void btn_log_clicked(); //登录按钮按下后触发的事件

private:

Ui::LogWidget *ui;

QString m_username;

QString m_password;

};

logwidget.cpp

#include "logwidget.h"

#include "ui_logwidget.h"

LogWidget::LogWidget(QWidget *parent) :

QWidget(parent),

ui(new Ui::LogWidget)

{

ui->setupUi(this);

// connect

// 触发重置按钮的信号槽连接

connect(ui->btn_clear,SIGNAL(clicked()),this,SLOT(btn_clear_clicked()));

// 触发登录按钮的信号槽连接

connect(ui->btn_log,SIGNAL(clicked()),this,SLOT(btn_log_clicked()));

// 发出信号后关闭登录窗口的信号槽连接

connect(this,SIGNAL(close_window()),this,SLOT(close()));

ui->edit_pw->setEchoMode(QLineEdit::Password);//输入的时候就显示圆点

m_username = "wuyongwen";

m_password = "wuyongwen";

// 读取json文件

read_json();

}

void LogWidget::read_json()

{

//打开文件

QFile file(QApplication::applicationDirPath()+"/config.json");

if(!file.open(QIODevice::ReadOnly)) {

qDebug() << "File open failed!";

} else {

qDebug() <<"File open successfully!";

}

QJsonDocument jdc(QJsonDocument::fromJson(file.readAll()));

QJsonObject obj = jdc.object();

QString save_name_flag=obj.value("SAVE_NAME").toString();

QString save_password_flag=obj.value("SAVE_PASSWORD").toString();

message_init(save_name_flag,save_password_flag);

}

//根据json内容决定是否填充输入框

void LogWidget::message_init(QString flag1,QString flag2)

{

//qDebug() << flag1 << "^^^" << flag2 ;

if (flag1 == "1")

{

ui->edit_name->setText("wuyongwen");

ui->check_name->setChecked(true);

}

if(flag2 == "1")

{

ui->edit_pw->setText("wuyongwen");

ui->check_pw->setChecked(true);

}

}

// 清理输入栏

void LogWidget::btn_clear_clicked()

{

ui->edit_pw->clear();

ui->edit_name->clear();

}

//登录按钮按下后触发的事件

void LogWidget::btn_log_clicked()

{

QString name = ui->edit_name->text();

QString password = ui->edit_pw->text();

if (name == m_username && password == m_password)

{

emit(login());

write_json();

emit(close_window());

}

else

QMessageBox::information(this, "Warning","Username or Password is wrong !");

}

// 更新json文件

void LogWidget::write_json()

{

QFile file(QApplication::applicationDirPath()+"/config.json");

if(!file.open(QIODevice::WriteOnly)) {

qDebug() << "File open failed!";

} else {

qDebug() <<"File open successfully!";

}

QJsonObject obj;

bool flag = ui->check_name->isChecked();

if(flag == true)

{

obj["SAVE_NAME"] = "1";

}

else

obj["SAVE_NAME"] = "0";

flag = ui->check_pw->isChecked();

if(flag == true)

{

obj["SAVE_PASSWORD"] = "1";

}

else

obj["SAVE_PASSWORD"] = "0";

QJsonDocument jdoc(obj);

file.write(jdoc.toJson());

file.flush();

}

6. 防止主窗口和登录窗口同时打开

在main.cpp主函数中,注释掉主窗口的show()函数: main.cpp:

#include "mainwindow.h"

#include

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

MainWindow w;

// w.show();

return a.exec();

}

7.最终完整代码:

logwidget.h

#ifndef LOGWIDGET_H

#define LOGWIDGET_H

#include

#include

#include

#include

#include

#include

#include

namespace Ui {

class LogWidget;

}

class LogWidget : public QWidget

{

Q_OBJECT

public:

explicit LogWidget(QWidget *parent = nullptr);

~LogWidget();

void form_init(); //格式初始化

void func_init(); //功能初始化

void read_json();

void write_json();

void message_init(QString flag1,QString flag2);

signals:

void login(); //登录主界面信号

void close_window(); //关闭登录界面信号

public slots:

void btn_clear_clicked(); //重置按钮按下后触发的事件

void btn_log_clicked(); //登录按钮按下后触发的事件

private:

Ui::LogWidget *ui;

QString m_username;

QString m_password;

};

#endif // LOGWIDGET_H

logwidget.cpp

#include "logwidget.h"

#include "ui_logwidget.h"

LogWidget::LogWidget(QWidget *parent) :

QWidget(parent),

ui(new Ui::LogWidget)

{

ui->setupUi(this);

form_init();

func_init();

}

LogWidget::~LogWidget()

{

delete ui;

}

void LogWidget::form_init()

{

// 文件标题名

ui->label_title->setGeometry(120,25,160,25);

ui->groupBox->setGeometry(50,60,300,125);

ui->label_name->setGeometry(25,25,100,25);

ui->edit_name->setGeometry(125,25,150,25);

ui->label_pw->setGeometry(25,75,100,25);

ui->edit_pw->setGeometry(125,75,150,25);

ui->check_name->setGeometry(85,200,100,25);

ui->check_pw->setGeometry(215,200,100,25);

ui->btn_log->setGeometry(50,235,120,30);

ui->btn_clear->setGeometry(230,235,120,30);

//调整字体大小

QFont font;

font.setPointSize(16); //实际上是16的字号,但设成16却不行

font.setFamily(("wenquanyi"));

font.setBold(false);

ui->label_title->setFont(font);

font.setPointSize(12);

ui->label_name->setFont(font);

ui->label_pw->setFont(font);

}

void LogWidget::func_init()

{

// connect

// 触发重置按钮的信号槽连接

connect(ui->btn_clear,SIGNAL(clicked()),this,SLOT(btn_clear_clicked()));

// 触发登录按钮的信号槽连接

connect(ui->btn_log,SIGNAL(clicked()),this,SLOT(btn_log_clicked()));

// 发出信号后关闭登录窗口的信号槽连接

connect(this,SIGNAL(close_window()),this,SLOT(close()));

ui->edit_pw->setEchoMode(QLineEdit::Password);//输入的时候就显示圆点

m_username = "sazass";

m_password = "123456";

read_json();

}

// 清理输入栏

void LogWidget::btn_clear_clicked()

{

ui->edit_pw->clear();

ui->edit_name->clear();

}

void LogWidget::btn_log_clicked()

{

QString name = ui->edit_name->text();

QString password = ui->edit_pw->text();

if (name == m_username && password == m_password)

{

emit(login());

write_json();

emit(close_window());

}

else

QMessageBox::information(this, "Warning","Username or Password is wrong !");

}

void LogWidget::read_json()

{

//打开文件

QFile file(QApplication::applicationDirPath()+"/config.json");

if(!file.open(QIODevice::ReadOnly)) {

qDebug() << "File open failed!";

} else {

qDebug() <<"File open successfully!";

}

QJsonDocument jdc(QJsonDocument::fromJson(file.readAll()));

QJsonObject obj = jdc.object();

QString save_name_flag=obj.value("SAVE_NAME").toString();

QString save_password_flag=obj.value("SAVE_PASSWORD").toString();

message_init(save_name_flag,save_password_flag);

}

void LogWidget::write_json()

{

QFile file(QApplication::applicationDirPath()+"/config.json");

if(!file.open(QIODevice::WriteOnly)) {

qDebug() << "File open failed!";

} else {

qDebug() <<"File open successfully!";

}

QJsonObject obj;

bool flag = ui->check_name->isChecked();

if(flag == true)

{

obj["SAVE_NAME"] = "1";

}

else

obj["SAVE_NAME"] = "0";

flag = ui->check_pw->isChecked();

if(flag == true)

{

obj["SAVE_PASSWORD"] = "1";

}

else

obj["SAVE_PASSWORD"] = "0";

QJsonDocument jdoc(obj);

file.write(jdoc.toJson());

file.flush();

}

void LogWidget::message_init(QString flag1,QString flag2)

{

//qDebug() << flag1 << "^^^" << flag2 ;

if (flag1 == "1")

{

ui->edit_name->setText("sazass");

ui->check_name->setChecked(true);

}

if(flag2 == "1")

{

ui->edit_pw->setText("123456");

ui->check_pw->setChecked(true);

}

}

mainwindow.h(省略无关内容)

#include "logwidget.h"

#include

QT_BEGIN_NAMESPACE

namespace Ui { class MainWindow; }

QT_END_NAMESPACE

class MainWindow : public QMainWindow

{

Q_OBJECT

public:

MainWindow(QWidget *parent = nullptr);

~MainWindow();

private:

Ui::MainWindow *ui;

LogWidget * m_log;

};

mainwindow.cpp(省略无关内容)

#include "mainwindow.h"

#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)

: QMainWindow(parent)

, ui(new Ui::MainWindow)

{

ui->setupUi(this);

m_log = new LogWidget;

m_log->show();

// 注意,这个信号槽的作用就是激活主窗口的,我们已经让主窗口不可以自动打开,

// 必须通过登录窗口中登录按钮发出的信号槽的信号才能打开

connect(m_log,SIGNAL(login()),this,SLOT(show()));

}

MainWindow::~MainWindow()

{

delete ui;

}

main.cpp

#include "mainwindow.h"

#include

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

MainWindow w;

// 这边把主窗口的show()函数,这样主窗口就不会自动打开,

// 必须通过登录窗口发出的信号,才能启动主窗口的show()函数。

// w.show();

return a.exec();

}

8. 源码分享

链接:https://pan.baidu.com/s/1gjTUdTLz0FXSRnqQq21Xiw?pwd=ot98 提取码:ot98 –来自百度网盘超级会员V5的分享

链接:https://pan.baidu.com/s/1SyLRjsLFpYiU9M7y1ZVw7Q?pwd=yloz 提取码:yloz –来自百度网盘超级会员V6的分享

9. 答疑

Q:用户信息的jeson文件保存到了哪里? A:直接对照 第7部分最终完整代码给出的代码,logwidget.cpp中的write_json()写入json文件(122行)和read_json()函数读取json文件(104行),里面QFile file(json文件地址) 代码中给出的QApplication::applicationDirPath()+"/config.json",默认在QT项目的一级目录下,保存的json文件命名为config.json。这里是写的是相对路径,也可以根据自己的需求进行更改,也可以修改为绝对路径。