Qt-数据库开发-用户登录、后台管理用户(6)

news2024/11/18 8:10:47

Qt-数据库开发-使用QSqlite数据库实现用户登录、后台管理用户功能

文章目录

  • Qt-数据库开发-使用QSqlite数据库实现用户登录、后台管理用户功能
    • 1、概述
    • 2、实现效果
    • 3、主要代码
    • 4、完整源代码

更多精彩内容
👉个人内容分类汇总 👈
👉数据库开发 👈

1、概述

开发环境说明

  • 系统:Windows10、Ubuntu20.04
  • Qt版本:V5.12.5
  • 编译器:MSVC2017-64、GCC/G++64

2、实现效果

  1. 通过按键新建 空白数据行;
  2. 使用自增Key;
  3. 通过按键更新数据;
  4. 判断表是否存在,不存在则创建。
  5. 用户登录功能,默认创建超级管理员账号root
  6. 支持用户后台管理,通过后台创建、修改、删除用户
  7. 用户分为超级管理员、普通管理员、普通用户三个等级;
  8. 超级管理员有所有权限,可创建、修改、删除普通管理员、普通用户;
  9. 普通管理员可创建、修改、删除普通用户,可新建、修改、查询数据;
  10. 普通用户不可修改用户信息,不可新建、修改数据库信息,只可查询。
  • 实现效果如下:

    在这里插入图片描述

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() << "指令执行失败";
        }
    }
    
    

4、完整源代码

  • github
  • gitee

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/77811.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UG环境设置

UG环境设置UG设置工作路径默认设置方法1&#xff1a; 修改快捷键路径方法2&#xff1a;修改“用户默认设置”UG设置窗口标题效果方法注意设置十字准线效果设置方法角色设置窗口布局效果方法命令搜索UG设置工作路径 默认设置 打开NX软件&#xff0c;新建模型默认路径如下&…

代码随想录算法训练营第三天| 链表理论基础, 203.移除链表元素,707.设计链表,206.反转链表

代码随想录算法训练营第三天| 链表理论基础&#xff0c; 203.移除链表元素&#xff0c;707.设计链表&#xff0c;206.反转链表 链表理论基础 建议&#xff1a;了解一下链接基础&#xff0c;以及链表和数组的区别 文章链接&#xff1a; 203.移除链表元素 建议&#xff1a; 本…

智源社区AI周刊No.109:ChatGPT预示大模型取代搜索引擎;Stable Diffusion2.1发布,8k高清图像生成...

汇聚每周AI热点&#xff0c;不错过重要资讯&#xff01;欢迎扫码&#xff0c;关注并订阅智源社区AI周刊。ChatGPT火出圈&#xff1a;对话大模型驱动新型搜索范式诞生&#xff0c;或将取代搜索引擎火出圈的ChatGPT注册用户数量已超过五百万&#xff0c;无疑是2022年最火的AI模型…

ReactNative MacOS环境初始化项目(安卓)

MacOS 12.6.1 官方文档 英文 https://reactnative.dev/docs/environment-setup中文 https://www.react-native.cn/docs/environment-setup 相关文档 ReactNative MacOS环境初始化项目(ios)OpenJDK 与 AdoptOpenJDK 的区别 安装步骤 安装Homebrew - /bin/zsh -c "$(curl -f…

spring学习记录(七)

Spring中对象分类 Spring是一个功能强大的容器&#xff0c;容器中存储的是一个一个的对象&#xff0c;容器中的对象分为&#xff1a; 简单对象复杂对象 简单对象就是可以通过构造器直接new 出来的对象&#xff1b; 复杂对象是不可以直接通过构造器直接new出来的对象。 无论是…

[附源码]Python计算机毕业设计SSM基于课程群的实验管理平台(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Java中异常处理方式

文章目录针对异常的处理主要有两种方式&#xff1a;1.抛出异常2.try catch 捕获异常三道经典异常处理代码题针对异常的处理主要有两种方式&#xff1a; 1.抛出异常 遇到异常不进行具体处理&#xff0c;而是继续抛给调用者&#xff08;throw&#xff0c;throws&#xff09;抛出…

java8新特性之toMap的用法——全网独一无二的通俗易懂的讲解

对于java8的新特性toMap方法&#xff0c;相信有很多人都在工作中用过&#xff0c;接下来就通俗易懂的讲解一下toMap吧 先来看看官网对于toMap方法的解释 toMap有个三个重载的方法&#xff0c;每一个重载方法的详解分别如下 &#xff08;1&#xff09;方法1&#xff1a;两个参…

SpringBoot整合kafka到底怎么使用? (简单案例介绍——存放104协议解析报文信息)

前言 由于业务要求&#xff0c;我需要将104协议的报文内容解析后传到kafka里&#xff0c;然后程序也是一个SpringBoot项目&#xff0c;所以本篇文章我想说一说我是如何将那些数据传到kafka中并判断其是否消费&#xff0c;至于104协议的报文内容的解析和通信在此不去介绍&#…

【javassist】javassist 入门案例 生成类

1.概述 前面介绍的ASM入门门槛还是挺高的,需要跟底层的字节码指令打交道,优点是小巧、性能好。Javassist是一个性能比ASM稍差但使用起来简单很多的字节码操作库,不需要使用者掌握字节码指令,由东京工业大学的数学和计算机科学系的教授Shigeru Chiba开发。 本节将分为两个…

2022卡塔尔世界杯。CSDN世界杯勋章来啦

卡塔尔世界杯正在如火如茶的举办着&#xff0c;在比赛场上&#xff0c;我看到了来自世界各地的球队&#xff0c;他们都充满活力&#xff0c;充满激情&#xff0c;每一支球队都在努力的拼搏&#xff0c;无论是为了胜利&#xff0c;还是为了荣誉。我看到了一支支优秀的球队&#…

前端分页处理

页面中实现的分页效果&#xff0c;要么后端提供接口&#xff0c;每次点击下一页就调用接口&#xff0c;若不提供接口&#xff0c;分页得前端自己去截取。 方法一&#xff1a;slice方法 slice(参数1&#xff0c;参数2)方法是返回一个新的数组对象&#xff0c;左开右闭 参数1&…

Mel spectrum梅尔频谱与MFCCs

梅尔频谱和梅尔倒谱MFCCs是使用非常广泛的声音特征形式。 1.Mel-spectrogram梅尔语谱图 机器学习的第一步都是要提取出相应的特征(feature)&#xff0c;如果输入数据是图片&#xff0c;例如28*28的图片&#xff0c;那么只需要把每个像素(pixel)作为特征&#xff0c;对应的像素…

【数据结构】链表定义及其常用的基本操作(C/C++)

目录 ●图示 ●链表类型定义 ●常用的基本操作&#xff08;单链表&#xff09; ●简单案例 ●图示 ●链表类型定义 1.单链表存储结构的定义 typedef struct lnode{elemtype data;struct lnode *next; }lnode,*linklist; 定义链表L&#xff1a;linklist &L&#x…

Windows系统服务器如何架设网站

Windows系统服务器如何架设网站 架设网站我们的需服务器必须要有iis功能&#xff0c;我们随便找个网站素材进行搭建 大家跟着我的步骤操作就可以啦 下面我们以Windows server 2008系统为例 右键我的电脑----管理-----角色-----web服务器&#xff08;iis&#xff09; Internet信…

值得一看!从0编写一份PID控制代码

【推荐阅读】 浅析linux 系统进程冻结&#xff08;freezing of task&#xff09; 深入linux内核架构--进程&线程 纯干货&#xff0c;linux内存管理——内存管理架构&#xff08;建议收藏&#xff09; 轻松学会linux下查看内存频率,内核函数,cpu频率 概述Linux内核驱动之GPI…

Servlet与表单、数据库综合项目实战【学生信息管理】

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;JAVA开发者…

开关电源环路稳定性分析(07)——电压型补偿网络

大家好&#xff0c;这里是大话硬件。 在前面的文章中&#xff0c;已经分析了控制级和功率级的传递函数&#xff0c;这一节咱们来分析反馈级的传递函数。 在分析反馈网络的传递函数之前&#xff0c;我想&#xff0c;应该有几个问题需要做一下介绍。 1. 功率级和控制级传递函数…

游戏开发41课 unity shader 优化

Shader有专门语言用来编写&#xff0c;常见类型有DirectX的HLSL&#xff0c;OpenGL的GLSL以及NVIDIA的Cg&#xff0c;为了优化shader代码&#xff0c;我们需要知道代码从被编写到被执行的流程&#xff0c;知道什么样的代码是不好的。 注意点&#xff1a; 避免if、switch分支语…

关于前端低代码的一些个人观点

2022&#xff0c;低代码彻底火了&#xff0c;甚至火到没有点相关经验&#xff0c;都不好意思出去面试的程度&#xff0c;堪称lowcode“元年”。在整个互联网大裁员的背景下&#xff0c;无论你是否相信它是降本提效的利器&#xff0c;彷佛都不重要了。因为行业趋势总是这般浩浩荡…