Qt-数据库开发-用户登录、后台管理用户
- [1] Qt-数据库开发-用户登录、后台管理用户
- 1、概述
- 2、实现效果
- [2] Qt使用SqlLite实现权限管理
- 初始化数据库
- 创建数据表
- 插入数据
- 可使用结构体对数据信息进行封装
- 数据库查询函数为
- 数据库更新数据函数为
- 删除数据函数为
- [3] 测试效果
[1] Qt-数据库开发-用户登录、后台管理用户
原文链接:https://blog.csdn.net/qq_43627907/article/details/128265671
1、概述
开发环境说明
系统:Windows10、Ubuntu20.04
Qt版本:V5.12.5
编译器:MSVC2017-64、GCC/G++64
2、实现效果
- 通过按键新建 空白数据行;
- 使用自增Key;
- 通过按键更新数据;
- 判断表是否存在,不存在则创建。
- 用户登录功能,默认创建超级管理员账号root
- 支持用户后台管理,通过后台创建、修改、删除用户
- 用户分为超级管理员、普通管理员、普通用户三个等级;
- 超级管理员有所有权限,可创建、修改、删除普通管理员、普通用户;
- 普通管理员可创建、修改、删除普通用户,可新建、修改、查询数据;
- 普通用户不可修改用户信息,不可新建、修改数据库信息,只可查询。
实现效果如下:
3、主要代码
啥也不说了,直接上代码,一切有注释
pro文件: Qt使用到数据库,上来什么都别管,先在pro文件添加上QT += sql ;
dialog.cpp文件:登录界面
#include "dialog.h"
#include "ui_dialog.h"
#include <QSqlQuery>
#include <qmessagebox.h>
#include <QDebug>
bool Dialog::m_loggedIn = false; // 登录状态
QString Dialog::m_userName; // 登录的用户名
UserBackstage::UserType Dialog::m_userType; // 用户类型
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
this->setWindowTitle("登录");
m_db = QSqlDatabase::addDatabase("QSQLITE"); // 使用数据库驱动(Qsqlite)和默认连接名称(qt_sql_default_connection)添加一个数据库
m_db.setDatabaseName("SignIn.db"); // 使用文件数据库(可生成数据库文件,数据一直有效)
if(!m_db.open()) // 打开数据库
{
QMessageBox::critical(nullptr, "Error", "打开数据库失败!");
return ;
}
// 创建一个用于保存用户信息的表
if(!isTableExists("User"))
{
QSqlQuery query;
// 创建一个表person,包含id、firstname、lastname三个字段
bool ret = query.exec("create table User ("
"id integer primary key," // 索引(自增key)
"userName varchar(20)," // 用户名
"password varchar(20)," // 密码
"type int)"); // 用户类型
if(!ret)
{
qDebug() << "创建表失败:";
}
else
{
QSqlQuery query;
query.prepare("insert into User(userName, password, type)"
"values (:userName, :password, :type)");
query.bindValue(":userName", "root");
query.bindValue(":password", "123456");
query.bindValue(":type", int(UserBackstage::Root));
query.exec();
}
}
}
Dialog::~Dialog()
{
if(m_db.isOpen())
{
m_db.close(); // 关闭数据库
}
delete ui;
}
/**
* @brief 返回登录状态
* @return true登录 false未登录
*/
bool Dialog::loggedIn()
{
return m_loggedIn;
}
/**
* @brief 返回登录的用户名
* @return 如果没有则为空
*/
QString Dialog::userName()
{
return m_userName;
}
/**
* @brief 返回登录的用户类型
* @return
*/
UserBackstage::UserType Dialog::type()
{
return m_userType;
}
/**
* @brief 判断表是否存在
* @param table
* @return
*/
bool Dialog::isTableExists(const QString &table)
{
QSqlQuery query;
QString sql = QString("select * from sqlite_master where name = '%1';").arg(table); // 查询sqlite_master表中是否存在表名
if(query.exec(sql))
{
return query.next();
}
return false;
}
/**
* @brief 登录
*/
void Dialog::on_but_signIn_clicked()
{
QString userName = ui->line_user->text().trimmed();
QString password = ui->line_password->text().trimmed();
if(userName.isEmpty())
{
QMessageBox::about(this, "注意!", "用户名不能为空");
return;
}
if(password.isEmpty())
{
QMessageBox::about(this, "注意!", "用户密码不能为空");
return;
}
// 从数据库中查询用户和密码,完成登录功能
QSqlQuery query;
QString sql = QString("select * from User where userName = '%1';").arg(userName); // 查询用户
if(query.exec(sql))
{
if(query.next()) // true则用户存在
{
if(password == query.value("password").toString()) // 密码相等
{
m_userName = userName;
m_userType = UserBackstage::UserType(query.value("type").toInt());
m_loggedIn = true;
this->close();
}
else
{
QMessageBox::about(this, "注意", "输入密码错误!");
}
}
else
{
QMessageBox::about(this, "注意", "用户不存在!");
}
}
else
{
QMessageBox::about(this, "注意", "sql指令执行失败!");
}
}
widget.cpp文件: 数据显示界面
#include "widget.h"
#include "ui_widget.h"
#include "dialog.h"
#include "userbackstage.h"
#include <QMessageBox>
#include <QSqlDatabase>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QString user;
switch (Dialog::type())
{
case UserBackstage::User:
{
ui->but_user->setVisible(false); // 隐藏用户管理功能
ui->but_add->setVisible(false); // 隐藏数据新建功能
ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); // 普通用户禁用修改数据功能
user = QString("普通用户:%1").arg(Dialog::userName());
break;
}
case UserBackstage::Admin:
{
user = QString("普通管理员:%1").arg(Dialog::userName());
break;
}
case UserBackstage::Root:
{
user = QString("超级管理员:%1").arg(Dialog::userName());
break;
}
}
this->setWindowTitle(QString("QSql-用户登录Demo - V%1 %2").arg(APP_VERSION).arg(user));
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_but_connect_clicked()
{
if(ui->but_connect->text() == "关闭数据库")
{
ui->but_connect->setText("连接数据库");
m_db.close();
}
else
{
m_db = QSqlDatabase::addDatabase("QSQLITE"); // 使用数据库驱动(Qsqlite)和默认连接名称(qt_sql_default_connection)添加一个数据库
// qDebug() << QSqlDatabase::defaultConnection; // 打印默认数据库连接名称
m_db.setDatabaseName("SignIn.db"); // 使用文件数据库(可生成数据库文件,数据一直有效)
if(!m_db.open()) // 打开数据库
{
QMessageBox::critical(nullptr, "Error", "打开数据库失败!");
return ;
}
// 如果表不存在则创建表
if(!isTableExists("person"))
{
QSqlQuery query;
// 创建一个表person,包含id、firstname、lastname三个字段
bool ret = query.exec("create table person ("
"id integer primary key," // 索引(自增key),使用integer默认为自增, int不能设置主键自增
"firstname varchar(20)," // 名
"lastname varchar(20))"); // 姓
if(!ret)
{
qDebug() << "创建表失败:";
}
}
initModel();
ui->but_connect->setText("关闭数据库");
}
}
/**
* @brief 判断表是否存在
* @param table 表名称
* @return true存在 false不存在
*/
bool Widget::isTableExists(const QString &table)
{
QSqlQuery query;
QString sql = QString("select * from sqlite_master where name = '%1';").arg(table); // 查询sqlite_master表中是否存在表名
if(query.exec(sql))
{
return query.next();
}
return false;
}
/**
* @brief SQL 表模型(QSqlTableModel)来编辑数据库中的信息
*/
void Widget::initModel()
{
if(m_model)
{
m_model->clear();
delete m_model;
m_model = nullptr;
}
m_model = new QSqlTableModel(this, m_db);
m_model->setTable("person"); // 设置需要显示的数据库表
#if 1
m_model->setEditStrategy(QSqlTableModel::OnFieldChange); // 在界面上修改后数据立刻保存到数据库
#else
m_model->setEditStrategy(QSqlTableModel::OnManualSubmit); // 将将编辑数据库中值的策略设置为[在调用 submitAll() 或 revertAll() 之前,所有更改都将缓存在模型中(即在界面上修改数据后不会立刻存入数据库)]
#endif
m_model->setHeaderData(0, Qt::Horizontal, "ID");
m_model->setHeaderData(1, Qt::Horizontal, "名称");
m_model->setHeaderData(2, Qt::Horizontal, "姓氏");
ui->tableView->setModel(m_model);
}
/**
* @brief 添加空白数据行
*/
void Widget::on_but_add_clicked()
{
QSqlQuery query;
query.prepare("insert into person(firstname, lastname)" // 写入数据时不需写入id字段,实现自增
"values (:firstname, :lastname)");
query.bindValue(":firstname", "");
query.bindValue(":lastname", "");
query.exec();
m_model->select(); // 获取数据库中的数据
}
/**
* @brief 查询数据库更新界面
*/
void Widget::on_but_read_clicked()
{
if(!m_model) return;
m_model->select(); // 获取数据库中的数据
ui->tableView->resizeColumnsToContents(); // 根据表格中的内容自动调整列宽
}
void Widget::on_but_user_clicked()
{
UserBackstage user;
user.setUserType(Dialog::type());
user.exec();
}
userbackstage.cpp文件: 用户管理后台
#include "userbackstage.h"
#include "ui_userbackstage.h"
#include <QDebug>
#include <qmessagebox.h>
#include <qsqlquery.h>
UserBackstage::UserBackstage(QWidget *parent) :
QDialog(parent),
ui(new Ui::UserBackstage)
{
ui->setupUi(this);
m_model = new QSqlTableModel(this);
m_model->setTable("User"); // 设置需要显示的数据库表
ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_model->setHeaderData(0, Qt::Horizontal, "ID");
m_model->setHeaderData(1, Qt::Horizontal, "用户名");
m_model->setHeaderData(2, Qt::Horizontal, "密码");
m_model->setHeaderData(3, Qt::Horizontal, "用户类型");
ui->tableView->setModel(m_model);
m_model->select(); // 获取数据库中的数据
ui->tableView->resizeColumnsToContents(); // 根据表格中的内容自动调整列宽
}
UserBackstage::~UserBackstage()
{
delete ui;
}
/**
* @brief 设置登录的用户类型
* @param type
*/
void UserBackstage::setUserType(UserBackstage::UserType type)
{
m_userType = type;
// 添加用户类型
ui->com_type->clear();
switch (type)
{
case User:
{
break;
}
case Admin:
{
ui->com_type->addItem("普通用户", User);
m_model->setFilter(QString("type = '%1'").arg(int(User))); // 只显示普通用户的信息
break;
}
case Root:
{
ui->com_type->addItem("普通用户", User);
ui->com_type->addItem("管理员", Admin);
break;
}
}
}
/**
* @brief 设置用户信息
*/
void UserBackstage::on_but_set_clicked()
{
QString userName = ui->line_user->text().trimmed();
QString password = ui->line_password->text().trimmed();
UserType userType = UserType(ui->com_type->currentIndex());
if(userName.isEmpty())
{
QMessageBox::about(this, "注意!", "用户名不能为空");
return;
}
if(password.isEmpty())
{
QMessageBox::about(this, "注意!", "用户密码不能为空");
return;
}
QSqlQuery query;
QString sql = QString("select * from User where userName = '%1';").arg(userName); // 查询用户
if(query.exec(sql))
{
if(query.next()) // true则用户存在则更新数据
{
int type = query.value("type").toInt();
if(type >= m_userType) // 如果修改的用户等级超过登录用户等级,则修改失败
{
return;
}
sql = QString("update User set password='%1', type=%2 where userName = '%3';")
.arg(password)
.arg(int(userType))
.arg(userName);
query.exec(sql);
}
else // 用户不存在则插入数据
{
query.prepare("insert into User(userName, password, type)"
"values (:userName, :password, :type)");
query.bindValue(":userName", userName);
query.bindValue(":password", password);
query.bindValue(":type", int(userType));
query.exec();
}
m_model->select(); // 获取数据库中的数据
}
else
{
qDebug() << "指令执行失败";
}
}
/**
* @brief 删除用户信息
*/
void UserBackstage::on_but_delete_clicked()
{
QString userName = ui->line_user->text().trimmed();
if(userName.isEmpty())
{
QMessageBox::about(this, "注意!", "用户名不能为空");
return;
}
QSqlQuery query;
QString sql = QString("delete from User where userName = '%1';").arg(userName); // 查询用户
if(query.exec(sql))
{
m_model->select(); // 获取数据库中的数据
}
else
{
qDebug() << "指令执行失败";
}
}
[2] Qt使用SqlLite实现权限管理
https://blog.csdn.net/weixin_41377572/article/details/127719446?ops_request_misc=&request_id=&biz_id=102&utm_term=qt%20%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-0-127719446.142v86insert_down1,239v2insert_chatgpt&spm=1018.2226.3001.4187
根据Sqlite轻量级数据库的优势,便于对于数据进行增删改查等操作。
本例模拟权限列表对不同界面进行权限管理,管理员针对不同人员进行权限设定,灵活性更高。
动态演示效果如下:
考虑数据库数据安全,可进行哈希散列值计算进行加密,Qt提供QCryptographicHash类进行数据加密,本例中使用的加密函数为:
QString SqlHelper::encode(QString str) {
QString strPwdSha = "";
if (str == "") {
return "";
}
QByteArray bytePwd = str.toLatin1();
QByteArray bytePwdSha = QCryptographicHash::hash(bytePwd, QCryptographicHash::Sha256);
strPwdSha = bytePwdSha.toHex().toUpper();
return strPwdSha;
}
QString SqlHelper::encodePwd(QString str) {
if (str == "") {
return "";
}
QString endata = encode(str);
QString strdata = "";
for (int i = 0; i < endata.size(); i++) {
if (i % 4 == 0) {
strdata += endata[i];
}
}
return strdata + "SAP";
}
初始化数据库
void SqlHelper::connectDataBase() {
db = QSqlDatabase::addDatabase("QSQLITE", "sqlite1");// 驱动类型,连接名(默认)
db.setDatabaseName("DbData/data.db");
db.setHostName("localhost.");
db.setUserName("root");
db.setPassword("123456");
m_DbState = db.open();
}
创建数据表
void SqlHelper::IniSql() {
QSqlQuery query(db);
QString strCmd = QString("create table employee(employee_id varchar(64) primary key,"
"employee_name varchar(64),employee_pass varchar(32),employee_settingrole varchar(16),"
"employee_menurole varchar(16),employee_logrole varchar(16),employee_sex varchar(16))");
query.prepare(strCmd);
if (query.exec())
{
qDebug() << "----employee 数据库表:创建成功!";
insertData("admin", "root", "root123456", 1,1,1,"male");
}
else {
qDebug() << "----employee 数据表已经存在-----";
}
}
插入数据
bool SqlHelper::insertData(QString userid, QString username, QString userpass, int sflag, int mflag, int lflag, QString usersex) {
if (!m_DbState) {
return false;
}
QList<employeeInfo> list = queryAllInfo();
m_mutex.lock();
bool flag = false;
//qDebug() << "m_id: " << m_id;
QSqlQuery query(db);
QString str = QString("insert into employee values(?,?,?,?,?,?,?)");
query.prepare(str);
//query.bindValue(0, list.size() + 1);
query.bindValue(0, userid);
query.bindValue(1, username);
QString pass = encodePwd(userpass);
query.bindValue(2, pass);
QString setrole = userid;
setrole.append(QString::number(sflag));
setrole = encodeRole(setrole,RoleType::SettingRole);
query.bindValue(3, setrole);
QString mrole = userid;
mrole.append(QString::number(mflag));
mrole = encodeRole(mrole, RoleType::MenuRole);
query.bindValue(4, mrole);
QString lrole = userid;
lrole.append(QString::number(lflag));
lrole = encodeRole(lrole, RoleType::LogRole);
query.bindValue(5, lrole);
query.bindValue(6, usersex);
if (query.exec()) {
qDebug() << "插入数据成功----";
flag = true;
}
else {
qDebug() << "插入数据失败----";
}
m_mutex.unlock();
//qDebug() << "777777777777777777777777";
return flag;
}
可使用结构体对数据信息进行封装
struct employeeInfo {
QString employee_id = "";
QString employee_name;
QString employee_pass;
QString employee_settingrole;
QString employee_menurole;
QString employee_logrole;
QString employee_sex;
};
数据库查询函数为
QList<employeeInfo> SqlHelper::queryAllInfo() {
QList<employeeInfo> list;
if (!m_DbState) {
return list;
}
m_mutex.lock();
QSqlQuery query(db);
QString str = "select * from employee";
query.prepare(str);
if (query.exec()) {
while (query.next()) {
//qDebug() << "name---" << query.value(1).toString() << " age-" << query.value(2).toInt();
employeeInfo employee;
employee.employee_id = query.value(0).toString();
employee.employee_name = query.value(1).toString();
employee.employee_pass = query.value(2).toString();
employee.employee_settingrole = query.value(3).toString();
employee.employee_menurole = query.value(4).toString();
employee.employee_logrole = query.value(5).toString();
employee.employee_sex = query.value(6).toString();
list.append(employee);
}
}
m_mutex.unlock();
return list;
}
employeeInfo SqlHelper::queryOne(QString userid) {
employeeInfo employee;
if (!m_DbState) {
return employee;
}
m_mutex.lock();
QSqlQuery query(db);
QString str = "select * from employee where employee_id =?";
query.prepare(str);
query.addBindValue(userid);
if (query.exec()) {
while (query.next()) {
employee.employee_id = query.value(0).toString();
employee.employee_name = query.value(1).toString();
employee.employee_pass = query.value(2).toString();
employee.employee_settingrole = query.value(3).toString();
employee.employee_menurole = query.value(4).toString();
employee.employee_logrole = query.value(5).toString();
employee.employee_sex = query.value(6).toString();
}
}
m_mutex.unlock();
return employee;
}
数据库更新数据函数为
bool SqlHelper::updateData(QString userid, QString username, QString userpass, int sflag ,int mflag, int lflag, QString usersex) {
if (!m_DbState) {
return false;
}
QSqlQuery query(db);
QString str = "update employee set employee_name =?,employee_pass=?,"
"employee_settingrole=?,employee_menurole=?,employee_logrole=? , employee_sex = ? where employee_id =?";
query.prepare(str);
query.addBindValue(username);
QString ss = queryPass(userid);
m_mutex.lock();
bool flag = false;
if (ss == userpass) {
query.addBindValue(ss);
}
else {
userpass = encodePwd(userpass);
query.addBindValue(userpass);
}
QString nsr = userid;
nsr.append(QString::number(sflag));
nsr = encodeRole(nsr, RoleType::SettingRole);
query.addBindValue(nsr);
QString nmr = userid;
nmr.append(QString::number(mflag));
nmr = encodeRole(nmr, RoleType::MenuRole);
query.addBindValue(nmr);
QString nlr = userid;
nlr.append(QString::number(lflag));
nlr = encodeRole(nlr, RoleType::LogRole);
query.addBindValue(nlr);
query.addBindValue(usersex);
query.addBindValue(userid);
if (query.exec()) {
flag = true;
qDebug() << "更新成功---";
}
else {
flag = false;
qDebug() << "更新失败---";
}
m_mutex.unlock();
return flag;
}
删除数据函数为
bool SqlHelper::deleteData(QString userid) {
if (!m_DbState) {
return false;
}
employeeInfo one = queryOne(userid);
if (one.employee_id == "") {
qDebug() << "此人已删除----";
return false;
}
m_mutex.lock();
bool flag = false;
QSqlQuery query(db);
QString str = "delete from employee where employee_id=?";
query.prepare(str);
query.addBindValue(userid);
if (query.exec()) {
flag = true;
qDebug() << "删除成功---";
}
else {
flag = false;
qDebug() << "删除失败---";
}
m_mutex.unlock();
return flag;
}
[3] 测试效果
“loginform.h”
#ifndef LOGINFORM_H
#define LOGINFORM_H
#include <QDialog>
#include <QDebug>
namespace Ui {
class LoginForm;
}
class LoginForm : public QDialog
{
Q_OBJECT
public:
enum UserType {
User, // 普通用户
Admin, // 普通管理员
Root // 超级管理员(唯一)
};
public:
explicit LoginForm(QWidget *parent = nullptr);
~LoginForm();
static bool loggedIn();
static QString userName();
static UserType type();
private slots:
void on_pBtn_Confirm_clicked();
void on_pBtn_Cancel_clicked();
private:
Ui::LoginForm *ui;
static UserType m_userType; //当前用户类型
static bool m_loggedIn; // 登录状态
static QString m_userName; // 登录的用户名
};
#endif // LOGINFORM_H
“loginform.cpp”
#include "loginform.h"
#include "ui_loginform.h"
LoginForm::UserType LoginForm::m_userType = LoginForm::UserType::User; //默认状态为普通用户
bool LoginForm::m_loggedIn = false; //默认状态为非登录状态
QString LoginForm::m_userName = "";
LoginForm::LoginForm(QWidget *parent) :
QDialog(parent),
ui(new Ui::LoginForm)
{
ui->setupUi(this);
setWindowTitle(tr("用户登录"));
//setWindowFlags(Qt::FramelessWindowHint);
ui->lineEdit_UserName->clear();
ui->lineEdit_Passwd->clear();
}
LoginForm::~LoginForm()
{
delete ui;
}
bool LoginForm::loggedIn()
{
return m_loggedIn;
}
QString LoginForm::userName()
{
return m_userName;
}
LoginForm::UserType LoginForm::type()
{
return m_userType;
}
void LoginForm::on_pBtn_Confirm_clicked()
{
QString name = ui->lineEdit_UserName->text().trimmed();
QString passwd = ui->lineEdit_Passwd->text().trimmed();
m_userName = name;
m_loggedIn = true;
m_userType = UserType::Root;
// qDebug()<<"Name: "<<name<<"\t passwd: "<<passwd;
this->close();
}
void LoginForm::on_pBtn_Cancel_clicked()
{
this->close();
}