QT肝8天16--加载动态菜单

1、动态菜单的实现方法

动态菜单通常指根据用户权限、角色或系统状态实时变化的菜单结构。Qt 提供了多种菜单控件,用于创建用户界面中的菜单栏、上下文菜单和弹出菜单,如QMenuBar。本项目控制菜单变化的模式是:用户--》角色--》菜单,控制方式简单粗爆管用,粒度大又管用,表结构如下:

2、不拖延,上干货

1、定义方法

这里定义的是结构体,如果使用类对象定义也是一样的

cpp 复制代码
#ifndef SQLITE3DB_H
#define SQLITE3DB_H
#include <QDateTime>
#include <QObject>


// 定义一个结构--表示用户
typedef struct {
    quint32 id;        // 用户Id
    QByteArray icon;   // 用户图标
    QString username;  // 用户名
    QString password;  // 密码
    QString name;      // 名称
    int gender;        // 性别
    QString addr;      // 地址
    QString phoneNo;   // 手机号
} OperatorInfo;

// 表示用户的集合
typedef QList<OperatorInfo> OperatorInfoList;
extern OperatorInfo* globalUserInfo;//定义全局变量,表示登录成功的用户

//数据库中的菜单结构
typedef struct {  // 描述一个菜单的信息
    int id;
    QString name;
    QString value;
    QString icon;
    int parentid;
} MenuItemInfo;
// 菜单带有层级
typedef struct {
    int id;
    QString name;
    QString value;
    QString icon;
    QList<MenuItemInfo> list;
} MenuItemRoot;



class Sqlite3Db
{
public:
    Sqlite3Db();

public:
    bool isContain(QString userName, QString passWord, OperatorInfo &infos); //根据用户和密码判断是否存在
    //分页查询
    bool selectOperators(QString searchString,int pageIndex,int pageSize,int &pageCount, OperatorInfoList &operatorinfs);//查询列表

    bool selectOperatorsById(qint64 id, OperatorInfo &operatorinf); //根据id查询

    bool insertOperator(const OperatorInfo &opt);//添加数据

    bool deleteOperator(qint64 id);//删除数据

    bool updateOperator(OperatorInfo info); // 更新数据

    //数据库查询菜单
    QList<MenuItemRoot> selectMenuRootItem(qint64 userid);//返回菜单数据
    QList<MenuItemInfo> findMenuInfoByPID(qint64 pid);//返回子菜单数据

};

#endif // SQLITE3DB_H

2、数据库实现方法

cpp 复制代码
#include "sqlite3db.h"
#include <QDebug>
#include <QtSql>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QList>

Sqlite3Db::Sqlite3Db() {}

OperatorInfo* globalUserInfo = nullptr;  // 初始化全局指针为nullptr

// Qt访问Sqlite的步骤:
// 1. 引入一个模块 QT       += core gui sql
// 2. 引入头文件
// 3. 使用QSqlDatabase 来进行操作

// 根据用户名和密码来判断,用户是否存在数据库中
bool Sqlite3Db::isContain(QString userName, QString passWord, OperatorInfo &infos) {
    QSqlDatabase db;
    db.setHostName("localhost");//设置主机名
    db = QSqlDatabase::addDatabase("QSQLITE");//添加数据库类型
    db.setDatabaseName("warehouse.db");  // 设置数据库名称
    db.open();//打开连接
    // bool isOpen = db.open();//打开连接
    //输出错误信息
    // qDebug() << isOpen ;
    // qDebug() << db.isValid();  // true
    // qDebug() << db.isOpen();   // true

    // 1.准备查询QSqlQuery 对象
    QSqlQuery query(db);
    // 2. 准备Sql语句? :占位符---避免sql注入
    QString sqlCmd = QString("SELECT * from operatorInfo where username=? and password=?");

    // 3.准备参数化占位符的数据
    query.prepare(sqlCmd);
    query.bindValue(0, userName);
    query.bindValue(1, passWord);

    //4.开始执行语句
    bool success = query.exec();
    if (success == false) {
        db.close();  // 网络资源,需要回收
        return false;
    }
    if (query.next() == false) {
        db.close();  // 网络资源,需要回收
        return false;
    }
    // 如果继续往后执行,就是已经买查询到对象了,返回这个对象的每个属性值
    OperatorInfo i;
    i.id = query.value(0).toInt();
    i.icon = query.value(1).toByteArray();
    i.username = query.value(2).toString();
    i.password = query.value(3).toString();
    i.addr = query.value(4).toString();
    i.gender = query.value(5).toInt();
    i.name = query.value(6).toString();
    i.phoneNo = query.value(7).toString();
    infos = i;
    db.close();
    return true;
}

// //查询列表
// bool Sqlite3Db::selectOperators(OperatorInfoList &operatorinfs)
// {
//     QSqlDatabase db;
//     db.setHostName("localhost");//设置主机名
//     db = QSqlDatabase::addDatabase("QSQLITE");//添加数据库类型
//     db.setDatabaseName("warehouse.db");  // 设置数据库名称
//     bool isOpen = db.open();//打开连接
//     //输出错误信息
//     qDebug() << isOpen ;
//     qDebug() << db.isValid();  // true
//     qDebug() << db.isOpen();   // true

//     // 1.准备查询QSqlQuery 对象
//     QSqlQuery query(db);
//     // 2. 准备Sql语句? :占位符---避免sql注入
//     QString sqlCmd = QString("SELECT * from operatorInfo ");
//     // 3.准备 数据
//     //query.prepare(sqlCmd);

//     //4.开始执行语句
//     bool success = query.exec(sqlCmd);
//     if (success == false) {
//         db.close();  // 网络资源,需要回收
//         OperatorInfoList list;
//         operatorinfs=list;
//         return false;
//     }

//     // 循环属性值
//     while(query.next()){
//         OperatorInfo i;
//         i.id = query.value(0).toInt();
//         i.icon = query.value(1).toByteArray();
//         i.username = query.value(2).toString();
//         i.password = query.value(3).toString();
//         i.addr = query.value(4).toString();
//         i.gender = query.value(5).toInt();
//         i.name = query.value(6).toString();
//         i.phoneNo = query.value(7).toString();
//         operatorinfs.push_back(i);
//     }
//     db.close(); // 网络资源,需要回收
//     return true;
// }


//查询列表,支持分页
bool Sqlite3Db::selectOperators(QString searchString,int pageIndex,int pageSize,int &pageCount, OperatorInfoList &operatorinfs)
{
    QSqlDatabase db;
    db.setHostName("localhost");//设置主机名
    db = QSqlDatabase::addDatabase("QSQLITE");//添加数据库类型
    db.setDatabaseName("warehouse.db");  // 设置数据库名称
    bool isOpen = db.open();//打开连接
    //输出错误信息
    qDebug() << isOpen ;
    qDebug() << db.isValid();  // true
    qDebug() << db.isOpen();   // true

    // 1.准备查询QSqlQuery 对象
    QSqlQuery query(db);
    // 2. 准备Sql语句? :占位符---避免sql注入
    QString strWhere=QString(" and 1=1");
    if(searchString.isNull()==false && searchString.isEmpty()==false){
        strWhere=QString("  and (name like '%%1%' or username like '%%2%')").arg(searchString).arg(searchString);
    }
    //查询分页数据
    QString datasql = QString("SELECT * from operatorInfo where 1=1 %1 limit %2 offset %3 ").arg(strWhere).arg(pageSize).arg((pageIndex - 1) * pageSize);
    //查询总页数
    QString pageCoutSql = QString("select count(id) from operatorInfo where 1=1 %1 ").arg(strWhere);

    //4.开始执行语句
    bool success = query.exec(datasql);
    if (success == false) {
        db.close();  // 网络资源,需要回收
        OperatorInfoList list;
        operatorinfs=list;
        return false;
    }

    // 循环属性值
    while(query.next()){
        OperatorInfo i;
        i.id = query.value(0).toInt();
        i.icon = query.value(1).toByteArray();
        i.username = query.value(2).toString();
        i.password = query.value(3).toString();
        i.addr = query.value(4).toString();
        i.gender = query.value(5).toInt();
        i.name = query.value(6).toString();
        i.phoneNo = query.value(7).toString();
        operatorinfs.push_back(i);//将数据添加到列表中
    }

    // 开始查询总条数,计算总页数
    bool success2 = query.exec(pageCoutSql);
    if (success2) {
        if (query.next()) {
            int dataCount = query.value(0).toInt();
            pageCount = dataCount / pageSize;
            if (dataCount % pageSize > 0) {
                pageCount = pageCount + 1;
            }
        }
    }
    db.close(); // 网络资源,需要回收
    return true;
}



//添加数据
bool Sqlite3Db::insertOperator(const OperatorInfo &opt)
{
    QSqlDatabase db;
    db.setHostName("localhost");//设置主机名
    db = QSqlDatabase::addDatabase("QSQLITE");//添加数据库类型
    db.setDatabaseName("warehouse.db");  // 设置数据库名称
    db.open();//打开连接
    //bool isOpen = db.open();//打开连接
    qDebug() << db.isOpen();   // true

    // 1.准备查询QSqlQuery 对象
    QSqlQuery query(db);
    // 2. 准备Sql语句
    query.prepare("insert into operatorInfo(icon,username,password,addr,gender,name,phoneNo) values (?,?,?,?,?,?,?);");
    query.bindValue(0, opt.icon);
    query.bindValue(1, opt.username);
    query.bindValue(2, opt.password);
    query.bindValue(3, opt.addr);
    query.bindValue(4, opt.gender);
    query.bindValue(5, opt.name);
    query.bindValue(6, opt.phoneNo);

    //3.开始执行语句
    bool success = query.exec();
    db.close(); // 网络资源,需要回收
    return success;
}

//删除数据
bool Sqlite3Db::deleteOperator(qint64 id)
{
    QSqlDatabase db;
    db.setHostName("localhost");//设置主机名
    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("warehouse.db");  // 设置数据库名称
    db.open();
    QSqlQuery query(db);
    query.prepare("delete from operatorInfo where id=?");
    query.bindValue(0, id);
    bool success = query.exec();
    db.close();
    return success;
}


//根据id查询一条数据
bool Sqlite3Db::selectOperatorsById(qint64 id, OperatorInfo &operatorinfo)
{
    QSqlDatabase db;
    db.setHostName("localhost");//设置主机名
    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("warehouse.db");  // 配置数据库的地址
    db.open();
    QSqlQuery query(db);

    query.prepare("SELECT * from operatorInfo where id=?");
    query.bindValue(0, id);
    bool success = query.exec();
    if (success & query.next()) {
        operatorinfo.id = query.value(0).toInt();
        operatorinfo.icon = query.value(1).toByteArray();
        operatorinfo.username = query.value(2).toString();
        operatorinfo.password = query.value(3).toString();
        operatorinfo.addr = query.value(4).toString();
        operatorinfo.gender = query.value(5).toInt();
        operatorinfo.name = query.value(6).toString();
        operatorinfo.phoneNo = query.value(7).toString();
        db.close();  // 网络资源,需要回收
        return true;
    }
    return false;
}


// 更新数据
bool Sqlite3Db::updateOperator(OperatorInfo info) {
    QSqlDatabase db;
    if (QSqlDatabase::contains("qt_sql_default_connection")) {
        db = QSqlDatabase::database("qt_sql_default_connection");
    } else{
        db = QSqlDatabase::addDatabase("QSQLITE");
    }
    db.setHostName("localhost");//设置主机名
    db.setDatabaseName("warehouse.db");  // 设置数据库名
    db.open();                           // 打开连接

    QString sqlCmd = QString("update operatorInfo set icon = ?,username = ?,addr = ?,gender = ?,name = ?,phoneNo = ? where id = ?");

    QSqlQuery query(db);
    query.prepare(sqlCmd);
    query.bindValue(0, info.icon);
    query.bindValue(1, info.username);
    query.bindValue(2, info.addr);
    query.bindValue(3, info.gender);
    query.bindValue(4, info.name);
    query.bindValue(5, info.phoneNo);
    query.bindValue(6, info.id);
    bool success = query.exec();
    if (!success) {
        qDebug() << "Error executing SQL statement:" << query.lastError().text();
    }
    db.close();
    return success;
}



//返回数据库菜单
QList<MenuItemRoot> Sqlite3Db::selectMenuRootItem(qint64 userid)
{
    QList<MenuItemRoot> menulist;
    QSqlDatabase db;
    db.setHostName("localhost");//设置主机名
    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("warehouse.db");  // 配置数据库的地址
    db.open();
    QSqlQuery query(db);
    query.prepare("select * from menuitems where id in (select menuID from menurole where roleID=(select roleID from userrole where userID=?))");
    query.bindValue(0, userid);
    bool success = query.exec();
    if (success) {
        while(query.next()){
            MenuItemRoot root;
            root.id = query.value(0).toInt();
            root.name = query.value(1).toString();
            root.value = query.value(2).toString();
            root.icon = query.value(3).toString();
            menulist.push_back(root);
        }
    }
    db.close(); // 网络资源,需要回收
    return menulist;
}

//根据父id获取二级菜单
QList<MenuItemInfo> Sqlite3Db::findMenuInfoByPID(qint64 pid)
{
    QList<MenuItemInfo> itemlist;
    QSqlDatabase db;
    db.setHostName("localhost");//设置主机名
    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("warehouse.db");  // 配置数据库的地址
    db.open();
    QSqlQuery query(db);

    query.prepare("select * from menuitems where parentid=?");
    query.bindValue(0, pid);
    bool success = query.exec();
    if (success) {
        while(query.next()){
            MenuItemInfo menuitem;
            menuitem.id = query.value(0).toInt();
            menuitem.name = query.value(1).toString();
            menuitem.value = query.value(2).toString();
            menuitem.icon = query.value(3).toString();
            menuitem.parentid = query.value(4).toInt();
            itemlist.push_back(menuitem);
        }
    }
    db.close(); // 网络资源,需要回收
    return itemlist;
}

3、生成左侧菜单

4、处理登录信息

5、登录与主界面关联

6、运行测试

管理员登录

换个用户登录

复制代码
原创不易,打字不易,截图不易,撸码不易,整理不易,走过路过,不要错过,欢迎点赞,收藏,转载,复制,抄袭,留言,灌水,请动动你的金手指,祝您早日实现财务自由。
相关推荐
友友马2 小时前
『 QT 』Qt初识
开发语言·qt
listhi5202 小时前
基于MATLAB的高斯混合模型(GMM)实现
开发语言·matlab
兰亭妙微2 小时前
兰亭妙微QT软件开发经验:跨平台桌面端界面设计的三大要点
开发语言·qt
Mingze03142 小时前
考研408之栈与队列学习
开发语言·c++·学习·考研·算法
循环渐进Forward3 小时前
Go语言:给AI开发装上高性能引擎
开发语言·人工智能·golang
数据知道3 小时前
Go基础:用Go语言操作MySQL详解
开发语言·数据库·后端·mysql·golang·go语言
励志不掉头发的内向程序员3 小时前
【Linux系列】并发世界的基石:透彻理解 Linux 进程 — 进程状态
linux·运维·服务器·开发语言·学习
掘根3 小时前
【Qt】事件
开发语言·qt
毕设源码-赖学姐3 小时前
【开题答辩全过程】以 Python在浙江省人口流动数据分析与城市规划建议的应用为例,包含答辩的问题和答案
开发语言·python·数据分析