QT+mysql实现一个功能齐全超市管理系统(可用于期末项目参考)

1 简介

        本章介绍一个较为齐全的超市管理系统,具有登录模块,商品,员工信息管理,数据分析,日志五大功能,其中员工,商品信息具有分页功能,数据分析使用饼图实现

2 效果展示

2.1 登录模块

                2.1.1界面

                

                2.1.2账号未输入

                

                2.1.3密码未输入

                

                2.1.4账号密码错误

                

                2.1.5非管理员登录

                

                2.1.6 无法连接数据库

                

2.2 员工管理

        2.2.1 界面

        

        2.2.2 新增员工

        

        2.2.3 修改员工信息

        

        2.2.4删除员工

        

     2.3 商品管理

        2.3.1 界面

        

        2.3.2 新增商品

        

        2.3.3 修改商品信息

        

        2.2.4删除商品信息

        

2.4数据分析(饼图)

        

2.5日志

3 数据库设计

商品信息表t_goods

员工信息表t_log

日志信息表t_worker

DDL语句:

CREATE TABLE `t_goods` (
  `id` int NOT NULL COMMENT '商品编号',
  `name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL COMMENT '商品名称',
  `num` int NOT NULL COMMENT '商品数量',
  `price` double(10,2) NOT NULL COMMENT '商品价格',
  `kind` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL COMMENT '商品种类',
  `picture` mediumblob COMMENT '商品图片',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin ROW_FORMAT=DYNAMIC;

CREATE TABLE `t_log` (
  `logid` int NOT NULL AUTO_INCREMENT,
  `operator` varchar(255) NOT NULL,
  `creationtime` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  `action` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  PRIMARY KEY (`logid`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE `t_worker` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '职工编号',
  `name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL COMMENT '职工姓名',
  `phone` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin DEFAULT NULL COMMENT '职工电话',
  `usename` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL COMMENT '职工账号',
  `password` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL COMMENT '职工密码',
  `address` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin DEFAULT NULL COMMENT '职工联系地址',
  `picture` mediumblob COMMENT '职工照片',
  `permissions` varchar(5) COLLATE utf8mb3_bin DEFAULT 'basic' COMMENT '权限:只有basic和admin',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin ROW_FORMAT=DYNAMIC;

4软件主要代码

  4.1 文件结构

4.2 代码分析

        mainwindow.h

        这里提供了一个访问Mysql数据库的静态方法 createMySqlConn()

        本程序使用ODBC连接数据库,大家可以去其他博主的文章获取教程,这里记得把数据库账号密码改成自己的

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include "insertgoods.h"
#include "insertworker.h"
#include "deletecomfirm.h"
#include "updategoods.h"
#include "updateworker.h"
#include "global.h"

#include <QMainWindow>
#include <QSqlDatabase>
#include <QDialog>
#include <QGraphicsDropShadowEffect>
#include <QSqlTableModel>
#include <QTableView>
#include <QSqlQuery>
#include <QFont>
#include <QPalette>
#include <QLinearGradient>
#include <QtCharts/QPieSeries>
#include <QtCharts/QPieSlice>
#include <QtCharts/QChartView>

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void DataBaseInit();//创建TableWidget
    void showAllGoodsTableWidget(int currentPage,int PageSize,int col,QString myGoodsName,QString myKind);//查询数据库并将数据显示在TW上
    void showBtn(int currentPage,int row,int PageSize);//控制上下页按钮的显示
    void setGoodslistCountPageLab(int rowCount);//设置商品页码总数
    int resultRowCount(QSqlQuery all);//返回列表查询行数
    void setWorkerTableRuler();//设置员工表的一些规则
    void showAllWorkerTableWidget(int currentPage_2,int PageSize,int col_2,QString myWorkerName,QString myPhone);//查询数据库并将数据显示在TW上
    void setWorkerlistCountPageLab(int rowCount);//设置员工页码总数
    void showBtn_2(int currentPage_2,int r,int PageSize);//控制员工列表上下页按钮的显示
    void createPiecharts();//饼图
    void setLogTableRuler();//log table属性
    void updateLog(QString action);//更新日志
    void showAllLog();//打印日志表

public slots:
     void on_resetButton_clicked();

     void on_resetButton_2_clicked();

private slots:
    void on_prevButton_clicked();

    void on_nextButton_clicked();

    void on_searchButton_clicked();

    void on_kindBox_currentTextChanged(const QString &arg1);

    void on_insertButton_clicked();

    void on_prevButton_2_clicked();

    void on_nextButton_2_clicked();

    void on_searchButton_2_clicked();

    void on_insertButton_2_clicked();

    void on_deleteWorkerButton_clicked();

    void on_deleteGoodsButton_clicked();

    void on_updateGoodsButton_clicked();

    void on_updateWorkerButton_clicked();

    void on_refreshBtn_clicked();

    void on_refreshLogButton_clicked();

private:
    Ui::MainWindow *ui;
    int currentPage;//商品当前页
    int currentPage_2;//员工当前页
    int PageSize;//每页大小
    int col;//商品表格列数
    int row;//商品表总行数
    int col_2;//员工表格列数
    int row_2;//员工表总行数
    QString myKind;//下拉框选择的商品类型
    QString myGoodsName;//输入的商品名字
    QString myWorkerName;//输入的员工名字
    QString myPhone;//输入的员工电话
};

//访问Mysql数据库的静态方法
static bool createMySqlConn(){
    QSqlDatabase db;
    //连接数据库
    db = QSqlDatabase::addDatabase("QODBC"); //加载数据库驱动

    db.setDatabaseName("supermarket"); //是在ODBC中创建的Datasourcename
    db.setHostName("localhost");
    db.setUserName("root");
    db.setPassword("123321ABCDEFG??");
    if(db.open()){
        qDebug() <<"数据库连接成功";
        return true;
    }else{
        qDebug() <<"数据库连接失败";
        return false;
    }
}

#endif // MAINWINDOW_H

mainwindow.cpp

主要函数介绍

setLogTableRuler():设置日志表格的一些属性

updateLog(QString action):更新日志信息

DataBaseInit():初始化表格参数,分页参数

setWorkerTableRuler():设置表格的一些属性

on_prevButton_clicked():上一页按钮实现

on_nextButton_clicked():下一页按钮实现

showAllGoodsTableWidget(int currentPage,int PageSize,int col,QString myGoodsName,QString myKind):打印出商品信息

showAllWorkerTableWidget(int currentPage_2,int PageSize,int col_2,QString myWorkerName,QString myPhone):打印出员工信息

showBtn(int currentPage,int row,int PageSize):控制上下页按钮的显示(即第一页不显示上一页,最后一页不显示下一页)

on_kindBox_currentTextChanged(const QString &arg1):获取下拉框数据

on_searchButton_clicked():搜索按钮实现

setWorkerlistCountPageLab(int rowCount):设置总页数

resultRowCount(QSqlQuery all):获取从数据库查询到的信息行数

on_resetButton_clicked():重置搜索框与刷新表

on_insertButton_clicked():新增商品按钮实现

on_deleteWorkerButton_clicked():删除员工信息按钮实现

on_deleteGoodsButton_clicked():删除商品信息按钮实现

on_updateGoodsButton_clicked():更新商品信息按钮实现

on_updateWorkerButton_clicked():更新员工信息按钮实现

createPiecharts():实现饼图展示

showAllLog():展示log表

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //阴影边框效果
    QGraphicsDropShadowEffect *shadow =new QGraphicsDropShadowEffect();
    shadow->setBlurRadius(20);
    shadow->setColor(Qt::black);

    // 设置窗口属性
    Qt::WindowFlags flags = this->windowFlags();
    flags &= ~Qt::WindowMaximizeButtonHint;  // 删除全屏按钮
    this->setWindowFlags(flags);

    ui->goodsTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);//只能选择一个单元格或一行进行操作。
    ui->goodsTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);//点击某个单元格时,整行将被选中
    ui->goodsTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);//无法直接在表格中编辑单元格内容
    ui->goodsTableWidget->horizontalHeader()->setStretchLastSection(true);//使最后一列自动填充剩余空间
    ui->goodsTableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);//平均分配行宽

    //电话输入框只能输入11位数字
    QRegularExpression regExp( "0|[1-9]\\d{0,10}" );
    ui->phoneEdit->setValidator(new QRegularExpressionValidator(regExp,this));

    setWorkerTableRuler();
    setLogTableRuler();
    DataBaseInit();
    createPiecharts();//饼图

    showAllLog();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setLogTableRuler(){
    // 设置表格的列数和行数
    ui->logWidget->setColumnCount(4);

    QStringList header;
    header<<"ID"<<"执行者"<<"操作"<<"时间";
    ui->logWidget->setHorizontalHeaderLabels(header);
    // 设置列宽度均分
    int columnWidth = ui->logWidget->width() / 4;
    for (int i = 0; i < 4; i++) {
        ui->logWidget->setColumnWidth(i, columnWidth);
    }
    ui->logWidget->setColumnWidth(0, 120);
    ui->logWidget->setColumnWidth(1, 120);
    ui->logWidget->setColumnWidth(2, 150);
    ui->logWidget->setColumnWidth(3, 380);
    // 禁止调整列宽
    ui->logWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
}

void MainWindow::updateLog(QString action){
    QSqlQuery query;
    query.prepare("INSERT into t_log(operator,creationtime,action) VALUES(:Operator,NOW(),:action)");
    query.bindValue(":Operator", GlobalData::Operator);
    query.bindValue(":action", action);

    bool success = query.exec();
    if(success){
        qDebug() << "日志更新成功";
    } else {
        qDebug() << "日志更新失败";
    }
}

void MainWindow::DataBaseInit(){
    // 设置分页参数
    currentPage = 1;
    currentPage_2=1;
    PageSize = 3;
    myGoodsName="";
    myKind="";
    myWorkerName="";
    myPhone="";

    // 创建数据模型
    QSqlTableModel *model = new QSqlTableModel();
    model->setTable("t_goods");
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    model->select();
    row = model->rowCount();//商品数据总行数
    col= model->columnCount();//商品数据总列数

    model->setTable("t_worker");
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    model->select();
    row_2 = model->rowCount();//员工数据总行数
    col_2= model->columnCount();//员工数据总列数

   //显示上下一页按钮
    showBtn(currentPage,row,PageSize);
    showBtn_2(currentPage_2,row_2,PageSize);

    // qDebug() << "商品列表总行数: "<<row;
    // qDebug() << "商品列表总列数: "<<col;
    // qDebug() << "员工列表总行数: "<<row_2;
    // qDebug() << "员工列表总列数: "<<col_2;

    ui->curPageLab->setText(QString::number(currentPage));
    ui->curPageLab_2->setText(QString::number(currentPage_2));

    setGoodslistCountPageLab(row);//设置页码总数
    setWorkerlistCountPageLab(row_2);//设置页码总数

    ui->goodsTableWidget->setColumnCount(col);
    ui->goodsTableWidget->setRowCount(PageSize);

    ui->workerTableWidget->setColumnCount(col_2-1);
    ui->workerTableWidget->setRowCount(PageSize);

    QStringList header;
    header<<"ID"<<"名称"<<"数量"<<"价格(元)"<<"种类"<<"展示图";
    ui->goodsTableWidget->setHorizontalHeaderLabels(header);

    QStringList header_2;
    header_2<<"ID"<<"姓名"<<"电话"<<"用户名"<<"地址"<<"照片"<<"权限";
    ui->workerTableWidget->setHorizontalHeaderLabels(header_2);

    showAllGoodsTableWidget(currentPage,PageSize,col,myGoodsName,myKind);
    showAllWorkerTableWidget(currentPage_2,PageSize,col_2,myWorkerName,myPhone);
}

void MainWindow::setWorkerTableRuler(){
    ui->workerTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);//只能选择一个单元格或一行进行操作。
    ui->workerTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);//点击某个单元格时,整行将被选中
    ui->workerTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);//无法直接在表格中编辑单元格内容
    ui->workerTableWidget->horizontalHeader()->setStretchLastSection(true);//使最后一列自动填充剩余空间
    ui->workerTableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);//平均分配行宽
}

void MainWindow::on_prevButton_clicked()
{
    currentPage--;
    ui->curPageLab->setText(QString::number(currentPage));
    showAllGoodsTableWidget(currentPage,PageSize,col,myGoodsName,myKind);
}

void MainWindow::on_nextButton_clicked()
{
    currentPage++;
    ui->curPageLab->setText(QString::number(currentPage));
    showAllGoodsTableWidget(currentPage,PageSize,col,myGoodsName,myKind);
}

void MainWindow::showAllGoodsTableWidget(int currentPage,int PageSize,int col,QString myGoodsName,QString myKind){
    ui->goodsTableWidget->clearContents();
    // 执行查询语句获取所有数据
    QSqlQuery currData;
    currData.exec("select * from t_goods WHERE name LIKE '%"+myGoodsName+"%' and kind LIKE '%"+myKind+"%' limit "+QString::number((currentPage-1)*PageSize)+","+QString::number(PageSize));

    // 将查询结果数据显示在TableWidget上
    int rowIndex = 0;
    QLabel *pieclabel;
    QTableWidgetItem* item;

    currData.first(); // 将查询结果指针移动到第一行
    while (currData.isValid()) {
        for (int colIndex = 0; colIndex < col; colIndex++) {
            if(colIndex == col-1){
                // 展示图片
                pieclabel = new QLabel;
                QPixmap photo;
                photo.loadFromData(currData.value(5).toByteArray(),"JPG");
                if(!photo.isNull()){
                    //图片自适应label大小
                    photo.scaled(pieclabel->size(),Qt::KeepAspectRatio);
                    pieclabel->setScaledContents(true);
                    pieclabel->setPixmap(photo.scaled(80,120));
                    ui->goodsTableWidget->setCellWidget(rowIndex,colIndex,pieclabel);
                }else{
                    item=new QTableWidgetItem("此商品没有图片。。");
                    item->setForeground(Qt::red); // 设置前景色为红色
                    ui->goodsTableWidget->setItem(rowIndex,colIndex,item);
                }
            }else{//除了图片列
                item = new QTableWidgetItem(currData.value(colIndex).toString());
                ui->goodsTableWidget->setItem(rowIndex, colIndex,item);
            }
        }
        rowIndex++;
        currData.next(); // 将查询结果指针移动到下一行
    }

    // 设置上下页按钮
    QSqlQuery all;
    all.exec("select * from t_goods WHERE name LIKE '%"+myGoodsName+"%' and kind LIKE '%"+myKind+"%'");
    int r = resultRowCount(all);//获取搜索到的总行数
    setGoodslistCountPageLab(r);
    showBtn(currentPage,r,PageSize);
}

void MainWindow::showAllWorkerTableWidget(int currentPage_2,int PageSize,int col_2,QString myWorkerName,QString myPhone){

    ui->workerTableWidget->clearContents();
    // 执行查询语句获取所有数据
    QSqlQuery currData2;
    currData2.exec("select * from t_worker WHERE name LIKE '%"+myWorkerName+"%' and phone LIKE '%"+myPhone+"%' limit "+QString::number((currentPage_2-1)*PageSize)+","+QString::number(PageSize));

    // 将查询结果数据显示在TableWidget上
    int rowIndex = 0;
    QLabel *pieclabel_2;
    QTableWidgetItem* item_2;

    currData2.first(); // 将查询结果指针移动到第一行
    while (currData2.isValid()) {
        for (int colIndex = 1; colIndex < col_2; colIndex++) {
            if(colIndex == 6){
                //  展示图片
                pieclabel_2 = new QLabel;
                QPixmap photo;
                photo.loadFromData(currData2.value(6).toByteArray(),"JPG");
                if(!photo.isNull()){
                    //图片自适应label大小
                    photo.scaled(pieclabel_2->size(),Qt::KeepAspectRatio);
                    pieclabel_2->setScaledContents(true);
                    pieclabel_2->setPixmap(photo.scaled(80,120));
                    ui->workerTableWidget->setCellWidget(rowIndex,colIndex-1,pieclabel_2);
                }else{
                    item_2=new QTableWidgetItem("此员工没有照片。。");
                    item_2->setForeground(Qt::red); // 设置前景色为红色
                    ui->workerTableWidget->setItem(rowIndex,colIndex-1,item_2);
                }
            }else if(colIndex == 7){
                item_2 = new QTableWidgetItem(currData2.value(7).toString());
                ui->workerTableWidget->setItem(rowIndex,colIndex-1,item_2);
            }else if(colIndex == 5){
                item_2 = new QTableWidgetItem(currData2.value(colIndex).toString());
                ui->workerTableWidget->setItem(rowIndex, colIndex-1,item_2);
            }else{
                item_2 = new QTableWidgetItem(currData2.value(colIndex-1).toString());
                ui->workerTableWidget->setItem(rowIndex, colIndex-1,item_2);
            }
        }
        rowIndex++;
        currData2.next(); // 将查询结果指针移动到下一行
    }

    // 设置上下页按钮
    QSqlQuery allworker;
    allworker.exec("select * from t_worker WHERE name LIKE '%"+myWorkerName+"%' and phone LIKE '%"+myPhone+"%'");
    int r = resultRowCount(allworker);//获取搜索到的总行数
    setWorkerlistCountPageLab(r);
    showBtn_2(currentPage_2,r,PageSize);
}

void MainWindow::showBtn(int currentPage,int row,int PageSize){
    if(row==PageSize||row==0){//只有一页全隐藏
        ui->prevButton->setVisible(false);
        ui->nextButton->setVisible(false);
    }else{
        if (currentPage == 1) {
            ui->prevButton->setVisible(false); // 如果 currentPage 等于 1,隐藏前一页按钮
        }
        else{
            ui->prevButton->setVisible(true);
        }

        if(currentPage == ceil(row/(double)PageSize)){// 如果 currentPage 等于 最后一页,隐藏下一页按钮,ceil向上取整
            ui->nextButton->setVisible(false);
        }
        else{
            ui->nextButton->setVisible(true);
        }
    }
}

void MainWindow::showBtn_2(int currentPage_2,int row,int PageSize){
    if(row==PageSize||row==0){//只有一页或没有数据全隐藏
        ui->prevButton_2->setVisible(false);
        ui->nextButton_2->setVisible(false);
    }else{
        if (currentPage_2 == 1) {
            ui->prevButton_2->setVisible(false); // 如果 currentPage 等于 1,隐藏前一页按钮
        }
        else{
            ui->prevButton_2->setVisible(true);
        }

        if(currentPage_2 == ceil(row/(double)PageSize)){// 如果 currentPage 等于 最后一页,隐藏下一页按钮,ceil向上取整
            ui->nextButton_2->setVisible(false);
        }
        else{
            ui->nextButton_2->setVisible(true);
        }
    }
}

void MainWindow::on_kindBox_currentTextChanged(const QString &arg1)
{
    // qDebug() << arg1;
    myKind = arg1;
}

void MainWindow::on_searchButton_clicked()
{
    myGoodsName = ui->goodsnameEdit->text();

    QSqlQuery mysearch;
    mysearch.exec("select * from t_goods WHERE name LIKE '%"+myGoodsName+"%' and kind LIKE '%"+myKind+"%'");
    int rowCount = resultRowCount(mysearch);//获取搜索到的总行数
    mysearch.clear();//不需要了

    if (rowCount>0) {
        // qDebug() << "查询结果非空,处理查询结果:";
        currentPage=1;//重回第一页
        ui->curPageLab->setText(QString::number(currentPage));
        showAllGoodsTableWidget(currentPage,PageSize,col,myGoodsName,myKind);
    } else {
        qDebug() << "查询结果为空";
        currentPage=1;//重回第一页
        ui->curPageLab->setText("0");
        ui->countPageLab->setText("0");
        showBtn(currentPage,0,PageSize);
        ui->goodsTableWidget->clearContents();
    }
}

void MainWindow::on_searchButton_2_clicked()
{
    myWorkerName = ui->workernameEdit->text();
    myPhone = ui->phoneEdit->text();

    QSqlQuery mySearchedWorker;
    mySearchedWorker.exec("select * from t_worker WHERE name LIKE '%"+myWorkerName+"%' and phone LIKE '%"+myPhone+"%'");
    int rowCount = resultRowCount(mySearchedWorker);//获取搜索到的总行数

    if (rowCount>0) {
        qDebug() << "员工查询结果非空,处理查询结果:";
        currentPage_2=1;//重回第一页
        ui->curPageLab_2->setText(QString::number(currentPage_2));
        showAllWorkerTableWidget(currentPage_2,PageSize,col_2,myWorkerName,myPhone);
    } else {
        qDebug() << "员工查询结果为空";
        currentPage_2=1;//重回第一页
        ui->curPageLab_2->setText("0");
        ui->countPageLab_2->setText("0");
        showBtn_2(currentPage_2,0,PageSize);
        ui->workerTableWidget->clearContents();
    }
}

void MainWindow::setGoodslistCountPageLab(int rowCount){
    //设置商品页码总数
    if(rowCount%3==0)
    {
        ui->countPageLab->setText(QString::number(rowCount/PageSize));
    }else{
        ui->countPageLab->setText(QString::number(rowCount/PageSize+1));
    }
}

void MainWindow::setWorkerlistCountPageLab(int rowCount){
    //设置员工页码总数
    if(rowCount%3==0)
    {
        ui->countPageLab_2->setText(QString::number(rowCount/PageSize));
    }else{
        ui->countPageLab_2->setText(QString::number(rowCount/PageSize+1));
    }
}

int MainWindow::resultRowCount(QSqlQuery all){
    //获取行数
    int resultRowCount = 0;
    if(all.last())
    {
        resultRowCount =  all.at() + 1;
        all.first();
        all.previous();
    }
    qDebug() << "查询出的总行数: " << resultRowCount;
    return resultRowCount;
}

void MainWindow::on_resetButton_2_clicked()
{
    ui->workernameEdit->clear();
    ui->phoneEdit->clear();
    myWorkerName = "";
    myPhone = "";
    currentPage_2=1;//重回第一页
    ui->curPageLab_2->setText(QString::number(currentPage_2));
    showAllWorkerTableWidget(currentPage_2,PageSize,col_2,myWorkerName,myPhone);
}

//重置按钮
void MainWindow::on_resetButton_clicked()
{
    ui->goodsnameEdit->clear();
    ui->kindBox->setCurrentIndex(0);
    myGoodsName = "";
    currentPage=1;//重回第一页
    ui->curPageLab->setText(QString::number(currentPage));
    showAllGoodsTableWidget(currentPage,PageSize,col,myGoodsName,myKind);
}

void MainWindow::on_prevButton_2_clicked()
{
    currentPage_2--;
    ui->curPageLab_2->setText(QString::number(currentPage_2));
    showAllWorkerTableWidget(currentPage_2,PageSize,col_2,myWorkerName,myPhone);
}

void MainWindow::on_nextButton_2_clicked()
{
    currentPage_2++;
    ui->curPageLab_2->setText(QString::number(currentPage_2));
    showAllWorkerTableWidget(currentPage_2,PageSize,col_2,myWorkerName,myPhone);
}

void MainWindow::on_insertButton_2_clicked()
{
    insertworker *iw = new insertworker;
    iw->setWindowModality(Qt::ApplicationModal);
    iw->show();
}

void MainWindow::on_insertButton_clicked()
{
    InsertGoods *ig = new InsertGoods;
    ig->setWindowModality(Qt::ApplicationModal);
    ig->show();
}

void MainWindow::on_deleteWorkerButton_clicked()
{
        QTableWidget* tableWidget = ui->workerTableWidget;
        // 获取选中的行索引
        int rowIndex = tableWidget->currentRow();
        // 确保有行被选中
        if(rowIndex>=0){
            // 获取需要删除的行的关键数据,比如ID
            QString rowId = tableWidget->item(rowIndex, 0)->text(); // 第一列是ID列
            int id = rowId.toInt();//转成int
            qDebug() << "rowData: " << id;
            // 弹出确认对话框
            QMessageBox::StandardButton reply;
            reply = QMessageBox::question(this, "确认删除", "确定要删除该行数据吗?", QMessageBox::Yes|QMessageBox::No);
            if (reply == QMessageBox::Yes){
                // 执行数据库删除操作
                QSqlQuery query;
                query.prepare("DELETE FROM t_worker WHERE id = :id");
                query.bindValue(":id", id); // 绑定id
                qDebug() << query.exec();
                if (query.exec())
                {
                    QMessageBox::information(this, "提示", "删除成功");
                    GlobalData::action = DELETE_WORKER;
                    updateLog(GlobalData::action);//更新日志
                    // 删除成功,更新UI
                    showAllWorkerTableWidget(currentPage_2,PageSize,col_2,myWorkerName,myPhone);
                }
                else
                {
                    // 删除失败,显示错误信息
                    QMessageBox::critical(this, "错误", "删除数据失败!");
                }
            }
        }else{
            // 没有选中行,显示提示信息
            QMessageBox::information(this, "提示", "请先选中要删除的行");
        }
}

void MainWindow::on_deleteGoodsButton_clicked()
{
    QTableWidget* tableWidget = ui->goodsTableWidget;
    // 获取选中的行索引
    int rowIndex = tableWidget->currentRow();
    // 确保有行被选中
    if(rowIndex>=0){
        // 获取需要删除的行的关键数据
        QString rowId = tableWidget->item(rowIndex, 0)->text(); // 第一列是ID列
        int id = rowId.toInt();//转成int
        qDebug() << "rowData: " << id;
        // 弹出确认对话框
        QMessageBox::StandardButton reply;
        reply = QMessageBox::question(this, "确认删除", "确定要删除该行数据吗?", QMessageBox::Yes|QMessageBox::No);
        if (reply == QMessageBox::Yes){
            // 执行数据库删除操作
            QSqlQuery query;
            query.prepare("DELETE FROM t_goods WHERE id = :id");
            query.bindValue(":id", id); // 绑定id
            qDebug() << query.exec();
            if (query.exec())
            {
                QMessageBox::information(this, "提示", "删除成功");
                GlobalData::action = DELETE_GOODS;
                updateLog(GlobalData::action);//更新日志
                // 删除成功,更新UI
                showAllGoodsTableWidget(currentPage,PageSize,col,myGoodsName,myKind);
            }
            else
            {
                // 删除失败,显示错误信息
                QMessageBox::critical(this, "错误", "删除数据失败!");
            }
        }
    }else{
        // 没有选中行,显示提示信息
        QMessageBox::information(this, "提示", "请先选中要删除的行");
    }
}

void MainWindow::on_updateGoodsButton_clicked()
{
    // GlobalData::goodsId = 13;
    QTableWidget* tableWidget = ui->goodsTableWidget;
    // 获取选中的行索引
    int rowIndex = tableWidget->currentRow();
    // 确保有行被选中
    if(rowIndex>=0){
        // 获取需要修改的行的关键数据
        QString rowId = tableWidget->item(rowIndex, 0)->text(); // 第一列是ID列
        QString rowName = tableWidget->item(rowIndex, 1)->text(); // 第2列是name列
        QString num = tableWidget->item(rowIndex, 2)->text(); // 第3列是数量列
        QString price = tableWidget->item(rowIndex, 3)->text(); // 第4列是价格列
        QString kind = tableWidget->item(rowIndex, 4)->text(); // 第5列是种类列
        GlobalData::goodsId = rowId.toInt();//转成int
        GlobalData::goodsName = rowName;
        GlobalData::num = num.toInt();
        GlobalData::price = price.toDouble();
        GlobalData::kind = kind;
        qDebug() << "goodsId: " << GlobalData::goodsId;
        qDebug() << "goodsName: " << GlobalData::goodsName;
        qDebug() << "num: " << GlobalData::num;
        qDebug() << "price: " << GlobalData::price;
        qDebug() << "kind: " << GlobalData::kind;

        //弹出新增页面
        updategoods *ug = new updategoods;
        ug->setWindowModality(Qt::ApplicationModal);
        ug->show();
    }else{
        // 没有选中行,显示提示信息
        QMessageBox::information(this, "提示", "请先选中要修改的行");
    }
}

void MainWindow::on_updateWorkerButton_clicked()
{
    QTableWidget* tableWidget = ui->workerTableWidget;
    // 获取选中的行索引
    int rowIndex = tableWidget->currentRow();
    // 确保有行被选中
    if(rowIndex>=0){
        // 获取需要修改的行的关键数据
        QString rowId = tableWidget->item(rowIndex, 0)->text(); // 第一列是ID列
        QString rowName = tableWidget->item(rowIndex, 1)->text(); // 第2列是name列
        QString phone = tableWidget->item(rowIndex, 2)->text(); // 第3列是电话列
        QString address = tableWidget->item(rowIndex, 4)->text(); // 第5列是地址列
        QString per = tableWidget->item(rowIndex, 6)->text(); // 第7列是权限列
        GlobalData::workId = rowId.toInt();//转成int
        GlobalData::workerName = rowName;
        GlobalData::phone = phone;
        GlobalData::address = address;
        GlobalData::permission = per;
        qDebug() << "workId: " << GlobalData::workId;
        qDebug() << "workerName: " << GlobalData::workerName;
        qDebug() << "phone: " << GlobalData::phone;
        qDebug() << "address: " << GlobalData::address;
        qDebug() << "permission: " << GlobalData::permission;

        //弹出新增页面
        updateworker *uw = new updateworker;
        uw->setWindowModality(Qt::ApplicationModal);
        uw->show();
    }else{
        // 没有选中行,显示提示信息
        QMessageBox::information(this, "提示", "请先选中要修改的行");
    }
}

void MainWindow::createPiecharts(){
    // 查询数据库中食品表的类型字段数据
    QSqlQuery query;
    query.exec("SELECT kind, COUNT(*) FROM t_goods GROUP BY kind");
    //成都与其他
    QSqlQuery query2;
    query2.exec("SELECT '包含成都' AS category, COUNT(*) AS count FROM t_worker WHERE address LIKE '%成都%' UNION ALL SELECT '不包含成都' AS category, COUNT(*) AS count FROM t_worker WHERE address NOT LIKE '%成都%'");

    int row=0;
    int row2=0;
    // 创建饼图数据模型
    QPieSeries *series = new QPieSeries();
    while (query.next()) {
        QString kind = query.value(0).toString();
        int count = query.value(1).toInt();
        series->append(kind, count);
        row++;
    }
    QPieSeries *series2 = new QPieSeries();
    while (query2.next()) {
        QString category = query2.value(0).toString();
        int count = query2.value(1).toInt();
        series2->append(category, count);
        row2++;
    }

    // 设置饼图的标签显示为百分比
    series->setLabelsVisible(true);
    series->setLabelsPosition(QPieSlice::LabelInsideHorizontal);
    foreach (QPieSlice *slice, series->slices()) {
        QString label = QString("%1: %2%").arg(slice->label()).arg(100 * slice->percentage(), 0, 'f', 1);
        slice->setLabel(label);
    }
    series2->setLabelsVisible(true);
    series2->setLabelsPosition(QPieSlice::LabelInsideHorizontal);
    foreach (QPieSlice *slice, series2->slices()) {
        QString label = QString("%1: %2%").arg(slice->label()).arg(100 * slice->percentage(), 0, 'f', 1);
        slice->setLabel(label);
    }

    QChart *chart = new QChart();
    // 设置饼图的大小
    chart->setPreferredSize(100, 100);
    chart->addSeries(series);
    chart->setTitle("商品各种类占比");
    chart->legend()->hide();

    QChart *chart2 = new QChart();
    // 设置饼图的大小
    chart2->setPreferredSize(100, 100);
    chart2->addSeries(series2);
    chart2->setTitle("成都人占比");
    chart2->legend()->hide();

    // 创建饼图视图和饼图视图窗口
    QChartView *chartView = new QChartView(chart);
    chartView->setRenderHint(QPainter::Antialiasing);

    QChartView *chartView2 = new QChartView(chart2);
    chartView2->setRenderHint(QPainter::Antialiasing);

    // 获取饼图视图的截图
    QPixmap pixmap = chartView->grab();
    ui->Pielabel->setPixmap(pixmap);

    QPixmap pixmap2 = chartView2->grab();
    ui->Pielabel_2->setPixmap(pixmap2);
}

void MainWindow::on_refreshBtn_clicked()
{
    createPiecharts();
}

void MainWindow::on_refreshLogButton_clicked()
{
    showAllLog();
}

void MainWindow::showAllLog(){
    ui->logWidget->clearContents();
    // 执行查询语句获取所有数据
    QSqlQuery currData;
    currData.exec("select * from t_log");

    // 设置表格的行数
    int rowCount = 0;
    while (currData.next()) {
        rowCount++;
    }
    ui->logWidget->setRowCount(rowCount);

    // 将查询结果数据显示在TableWidget上
    currData.first();
    int rowIndex = 0;
    currData.first(); // 将查询结果指针移动到第一行
    do {
        QString id = currData.value(0).toString();
        QString Op = currData.value(1).toString();
        QString time = currData.value(2).toString();
        QString action = currData.value(3).toString();

        QTableWidgetItem *itemid = new QTableWidgetItem(id);
        QTableWidgetItem *itemOp = new QTableWidgetItem(Op);
        QTableWidgetItem *itemtime = new QTableWidgetItem(time);
        QTableWidgetItem *itemaction = new QTableWidgetItem(action);

        ui->logWidget->setItem(rowIndex, 0, itemid);
        ui->logWidget->setItem(rowIndex, 1, itemOp);
        ui->logWidget->setItem(rowIndex, 2, itemaction);
        ui->logWidget->setItem(rowIndex, 3, itemtime);

        rowIndex++;
    } while (currData.next());
}

main.cpp

引入qss文件,与访问数据库,无法访问数据库则无法打开登录界面

#include "mainwindow.h"
#include "login.h"

#include <QApplication>
#include <QFile>
#include <QProcess>
#include <QDebug>
#include <QDialog>
#include <QMessageBox>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    //引入qss文件
    QFile LoginQssFile(":/qss/login.qss");
    QFile MainWindowQssFile(":/qss/mainwindow.qss");
    if(LoginQssFile.open(QFile::ReadOnly)&&MainWindowQssFile.open(QFile::ReadOnly)){
        // qDebug()<<"qss加载成功";
        a.setStyleSheet(LoginQssFile.readAll());
        a.setStyleSheet(MainWindowQssFile.readAll());
    }
    LoginQssFile.close();
    MainWindowQssFile.close();

    //提示框
    QMessageBox connDailedMsgBox;
    connDailedMsgBox.setWindowTitle("错误");
    connDailedMsgBox.setIcon(QMessageBox::Warning);
    connDailedMsgBox.setText("数据库连接失败");

    if(!createMySqlConn()){
        qDebug() << "数据库连接失败";
        connDailedMsgBox.exec();
        return 0;
    }else{
        Login w;
        w.show();
        return a.exec();
    }
}

globle.h

定义所需的全局变量

#ifndef GLOBAL_H
#define GLOBAL_H

#include <QByteArray>
#include <QString>

#define UPDATE_WORKER "更新了员工表"
#define DELETE_WORKER "删除一个员工"
#define UPDATE_GOODS "更新了商品表"
#define DELETE_GOODS "删除一个商品"

class GlobalData
{
public:
    static int goodsId;
    static QString goodsName;
    static int num;
    static double price;
    static QString kind;
    static QByteArray pic;

    static int workId;
    static QString workerName;
    static QString phone;
    static QString address;
    static QString permission;

    static QString Operator;
    static QString creationTime;
    static QString action;
};

#endif // GLOBAL_H

globle.cpp

初始化全局变量

#include "global.h"

int GlobalData::goodsId = 0;
QString GlobalData::goodsName = "";
int GlobalData::num = 0;
double GlobalData::price = 0;
QString GlobalData::kind = "食品";

int GlobalData::workId = 0;
QString GlobalData::workerName = "";
QString GlobalData::phone = "";
QString GlobalData::address = "";
QString GlobalData::permission = "basic";

QString GlobalData::Operator = "";
QString GlobalData::creationTime = "";
QString GlobalData::action = "";

login.h

#ifndef LOGIN_H
#define LOGIN_H

#include "mainwindow.h"
#include "global.h"

#include<QWidget>
#include<QSqlQuery>  //查询mysql数据库
#include<QSqlDatabase>
#include<QMessageBox>
#include<QCryptographicHash>  //包含MD5算法库
#include<QDialog>
#include<QPixmap>

namespace Ui {
class Login;
}

class Login : public QWidget
{
    Q_OBJECT

public:
    explicit Login(QWidget *parent = nullptr);
    ~Login();


private slots:
    void on_loginButton_clicked();

private:
    Ui::Login *ui;

};

#endif // LOGIN_H

login.cpp

on_loginButton_clicked():登录按钮实现

#include "login.h"
#include "ui_login.h"


Login::Login(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Login)
{
    ui->setupUi(this);

    // 设置窗口属性
    Qt::WindowFlags flags = this->windowFlags();
    flags &= ~Qt::WindowMaximizeButtonHint;  // 删除全屏按钮
    this->setWindowFlags(flags);

    //设置用户密码输入框之前的icon
    QPixmap *acountimage = new QPixmap(":/icon/acount.png");
    acountimage->scaled(ui->usernameIcon->size(), Qt::KeepAspectRatio);
    ui->usernameIcon->setScaledContents(true);
    ui->usernameIcon->setPixmap(*acountimage);
    QPixmap *pwdimage = new QPixmap(":/icon/pwd.png");
    pwdimage->scaled(ui->usernameIcon->size(), Qt::KeepAspectRatio);
    ui->pwdIcon->setScaledContents(true);
    ui->pwdIcon->setPixmap(*pwdimage);

    //设置密码模式
    ui->passwordEdit->setEchoMode(QLineEdit::Password);

    //用户名焦点
    ui->usernameEdit->setFocus();
    //回车触发登录信号槽
    connect(ui->passwordEdit, &QLineEdit::returnPressed, ui->loginButton, &QPushButton::click);

}

Login::~Login()
{
    delete ui;
}

//登录按钮
void Login::on_loginButton_clicked()
{
    QString username=ui->usernameEdit->text();
    QString password=ui->passwordEdit->text();

    //创建警告框
    QMessageBox NoPwdMsgBox;
    QMessageBox NoUserNameMsgBox;
    QMessageBox NotExistMsgBox;
    QMessageBox NotAdminMsgBox;
    NoPwdMsgBox.setWindowTitle("温馨提示");
    NoUserNameMsgBox.setWindowTitle("温馨提示");
    NotExistMsgBox.setWindowTitle("登录失败");
    NotAdminMsgBox.setWindowTitle("温馨提示");
    NoPwdMsgBox.setIcon(QMessageBox::Warning);
    NoUserNameMsgBox.setIcon(QMessageBox::Warning);
    NotExistMsgBox.setIcon(QMessageBox::Warning);
    NotAdminMsgBox.setIcon(QMessageBox::Warning);
    NoPwdMsgBox.setText("请输入密码");
    NoUserNameMsgBox.setText("请输入账号");
    NotExistMsgBox.setText("请输入正确的账号或密码");
    NotAdminMsgBox.setText("你不是管理员,无法登录此系统");

    if(username.isEmpty()){
        NoUserNameMsgBox.exec();
    }else if(password.isEmpty()){
        NoPwdMsgBox.exec();
    }else{

        // 执行条件查询
        QString queryStr = "SELECT * FROM t_worker WHERE usename = '"+username+"' and password = '"+password+"'";
        QString getNameQuery = "SELECT name FROM t_worker WHERE usename = '"+username+"' and password = '"+password+"'";//获取账号名用于日志
        QSqlQuery query;
        QSqlQuery getName;
        query.exec(queryStr);

        if (query.next()) {
            qDebug() << "查询管理员成功";
            // 获取权限
            QVariant value = query.value(7);
            // qDebug() << "权限:" << value.toString();
            if(value.toString().compare(QString::fromLocal8Bit("admin"))==0){
                //验证通过
                // 打开操作窗口
                getName.exec(getNameQuery);
                getName.first();
                GlobalData::Operator = getName.value(0).toString();//将username赋值给全局变量
                qDebug() << "Operator: " << GlobalData::Operator;
                this->hide();
                MainWindow *mw = new MainWindow;
                mw->show();
            }else{
                qDebug() << "不是管理员";
                NotAdminMsgBox.exec();
            }
        }else{
            qDebug() << "查询失败";
            NotExistMsgBox.exec();
        }
    }
}

insergoods.h

插入商品头文件,可供插入员工的头文件可以参考,由于篇幅原因就不详细说明了

#ifndef INSERTGOODS_H
#define INSERTGOODS_H

#include "global.h"
#include "mainwindow.h"

#include <QWidget>
#include <QSqlDatabase>
#include <QSqlTableModel>
#include <QSqlQuery>
#include <QRegularExpressionValidator>
#include <QMessageBox>
#include <QRegularExpression>
#include <QLabel>
#include <QFile>
#include <QEvent>
#include <QDialog>
#include <QFileDialog>
#include <QFile>

namespace Ui {
class InsertGoods;
}

class InsertGoods : public QWidget
{
    Q_OBJECT

public:
    explicit InsertGoods(QWidget *parent = nullptr);
    ~InsertGoods();
    void isValidate();
    bool isUniqueId(int id);//判断id唯一
    bool isUniqueName(QString name);//判断name唯一
    void insertGoods(int id,QString name,int num,double price,QString kind,QByteArray b);

protected:


private slots:
    void on_cancelButton_clicked();

    void on_insertButton_clicked();

    void on_kindBox_currentTextChanged(const QString &arg1);

    void on_uploadButton_clicked();

private:
    Ui::InsertGoods *ui;
    QString myKind;
    QByteArray imageData;//选择的图片
};

#endif // INSERTGOODS_H

insertgoods.cpp

on_insertButton_clicked():新增按钮事件

insertGoods(int id,QString name,int num,double price,QString kind,QByteArray b):实现数据插入数据库

isValidate():输入框输入限制

isUniqueId(int id):判断id是否唯一

isUniqueName(QString name):判断名字是否唯一

on_uploadButton_clicked():上传图片按钮实现

#include "insertgoods.h"
#include "ui_insertgoods.h"

InsertGoods::InsertGoods(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::InsertGoods)
{
    ui->setupUi(this);

     ui->idEdit->setFocus();
    ui->kindBox->setCurrentIndex(0);
    isValidate();//输入框验证
    myKind = "食品";
    imageData = NULL;
}

InsertGoods::~InsertGoods()
{
    delete ui;
}

void InsertGoods::on_kindBox_currentTextChanged(const QString &arg1)
{
    myKind = arg1;
}

void InsertGoods::on_cancelButton_clicked()
{
    this->close();
}

void InsertGoods::on_insertButton_clicked()
{
    int goodsId = (ui->idEdit->text()).toInt();
    QString goodsName = ui->nameEdit->text();
    int goodsNum = (ui->numEdit->text()).toInt();
    double goodsPrice = (ui->priceEdit->text()).toDouble();
    QString goodskind = myKind;

    isValidate();

    qDebug() << "goodsId: "<<goodsId;
    qDebug() << "goodsName: "<<goodsName;
    qDebug() << "goodsNum: "<<goodsNum;
    qDebug() << "goodsPrice: "<<goodsPrice;
    qDebug() << "goodskind: "<<goodskind;

    bool isUnique = isUniqueId(goodsId);
    bool nameIsUnique = isUniqueName(goodsName);
    if(ui->idEdit->text().isEmpty()){
        QMessageBox::warning(this, "警告", "ID不能为空!");
        ui->idEdit->setFocus();
    }else if(ui->nameEdit->text().isEmpty()){
        QMessageBox::warning(this, "警告", "名字不能为空!");
        ui->nameEdit->setFocus();
    }else if(ui->numEdit->text().isEmpty()){
        QMessageBox::warning(this, "警告", "数量不能为空!");
        ui->numEdit->setFocus();
    }else if(ui->priceEdit->text().isEmpty()){
        QMessageBox::warning(this, "警告", "价格不能为空!");
        ui->priceEdit->setFocus();
    }else{
        if(!isUnique){
            //id不是唯一
            QMessageBox::warning(this, "警告", "ID已经存在!");
            ui->idEdit->setFocus();
        }else if(!nameIsUnique){
            //name不是唯一
            QMessageBox::warning(this, "警告", "名字已经存在!");
            ui->nameEdit->setFocus();
        }else{
            insertGoods(goodsId,goodsName,goodsNum,goodsPrice,goodskind,imageData);
            this->close();
       }
    }
}

void InsertGoods::insertGoods(int id,QString name,int num,double price,QString kind,QByteArray b){
    QSqlQuery query;
    query.prepare("INSERT into t_goods VALUES (:id,:name,:num,:price,:kind,:picture)");
    query.bindValue(":id", id);
    query.bindValue(":name", name);
    query.bindValue(":num", num);
    query.bindValue(":price", price);
    query.bindValue(":kind", kind);
    query.bindValue(":picture", b);

    bool success = query.exec();
    if(success){
        GlobalData::action = UPDATE_GOODS;
        MainWindow m;
        m.updateLog(GlobalData::action);
        QMessageBox::information(this, "提示", "成功!");
        qDebug() << "Insert statement executed successfully";
    } else {
        qDebug() << "Failed to execute insert statement";
    }
}

void InsertGoods::isValidate(){
    //只能输入0到99999
    QRegularExpression regExp( "0|[1-9]\\d{0,4}" );
    ui->idEdit->setValidator(new QRegularExpressionValidator(regExp,this));
    ui->numEdit->setValidator(new QRegularExpressionValidator(regExp,this));

    //输入7个字符最多
    QRegularExpression regExp2( "^.{0,7}$" );
    ui->nameEdit->setValidator(new QRegularExpressionValidator(regExp2,this));

    //输入浮点数
    QRegularExpression regExp3( "^\\d+(\\.\\d{1,2})?$" );
    ui->priceEdit->setValidator(new QRegularExpressionValidator(regExp3,this));
}

bool InsertGoods::isUniqueId(int id){
    QSqlQuery query;
    query.prepare("SELECT * FROM t_goods WHERE id = :id");
    query.bindValue(":id", id);

    if (query.exec() && query.next()) {
        // 查询到数据,不是唯一
        qDebug() << "查询到数据,不是唯一";
        return false;
    } else {
        // 未查询到数据,是唯一
        qDebug() << "查询到数据,是唯一";
        return true;
    }
}

bool InsertGoods::isUniqueName(QString name){
    QSqlQuery query;
    query.prepare("SELECT * FROM t_goods WHERE name = :name");
    query.bindValue(":name", name);

    if (query.exec() && query.next()) {
        // 查询到数据,不是唯一
        qDebug() << "查询到数据,不是唯一";
        return false;
    } else {
        // 未查询到数据,是唯一
        qDebug() << "查询到数据,是唯一";
        return true;
    }
}

void InsertGoods::on_uploadButton_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this,
    tr("选择商品图片"), "", tr("Image Files (*.png *.jpg *.bmp)"));

    // 如果用户选择了一个文件
    if (!fileName.isEmpty()) {
        // 使用QPixmap加载图片
        QPixmap pixmap(fileName);
        qDebug() << "图片加载成功";
        // 将图片设置到标签上
        ui->goodsPic->setPixmap(pixmap.scaled(ui->goodsPic->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
        QFile imgFile(fileName);
        imgFile.open(QIODevice::ReadOnly);
        imageData = imgFile.readAll();
        imgFile.close();
    }
}

updateworker.h

更新员工头文件,可供更新商品参考,由于篇幅原因就不详细说明了

#ifndef UPDATEWORKER_H
#define UPDATEWORKER_H

#include "global.h"
#include "mainwindow.h"

#include <QWidget>
#include <QSqlDatabase>
#include <QSqlTableModel>
#include <QSqlQuery>
#include <QRegularExpressionValidator>
#include <QMessageBox>
#include <QRegularExpression>
#include <QLabel>
#include <QFile>
#include <QEvent>
#include <QDialog>
#include <QFileDialog>
#include <QFile>

namespace Ui {
class updateworker;
}

class updateworker : public QWidget
{
    Q_OBJECT

public:
    explicit updateworker(QWidget *parent = nullptr);
    ~updateworker();

    void isValidate();

    void updateWorker(int id,QString name,QString phone,QString address,QByteArray pic,QString permission);

private slots:
    void on_cancelButton_clicked();

    void on_uploadButton_clicked();

    void on_perBox_currentTextChanged(const QString &arg1);

    void on_updateWorkerButton_clicked();

private:
    Ui::updateworker *ui;
    QString permission;
    QByteArray imageData;//选择的图片
};

#endif // UPDATEWORKER_H

updateworker.cpp

on_cancelButton_clicked():取消按钮实现

on_uploadButton_clicked():上传图片按钮实现

isValidate():输入框规则

on_perBox_currentTextChanged(const QString &arg1):下拉框数据获取

on_updateWorkerButton_clicked():更新按钮事件

updateWorker(int id,QString name,QString phone,QString address,QByteArray pic,QString permission):更新数据

#include "updateworker.h"
#include "ui_updateworker.h"

updateworker::updateworker(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::updateworker)
{
    ui->setupUi(this);
    ui->perBox->setCurrentIndex(0);
    ui->nameEdit->setFocus();

    //更新弹出初始值
    ui->nameEdit->setText(GlobalData::workerName);
    ui->phoneEdit->setText(GlobalData::phone);
    ui->addressEdit->setText(GlobalData::address);
    if(GlobalData::permission=="basic"){
        permission = "basic";
        ui->perBox->setCurrentIndex(0);
    }else{
        permission = "admin";
        ui->perBox->setCurrentIndex(1);
    }

    imageData = NULL;

    isValidate();
}

updateworker::~updateworker()
{
    delete ui;
}

void updateworker::on_cancelButton_clicked()
{
    this->close();
}

void updateworker::on_uploadButton_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this,
    tr("选择商品图片"), "", tr("Image Files (*.png *.jpg *.bmp)"));

    // 如果用户选择了一个文件
    if (!fileName.isEmpty()) {
        // 使用QPixmap加载图片
        QPixmap pixmap(fileName);
        qDebug() << "图片加载成功";
        // 将图片设置到标签上
        ui->workerPic->setPixmap(pixmap.scaled(ui->workerPic->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
        QFile imgFile(fileName);
        imgFile.open(QIODevice::ReadOnly);
        imageData = imgFile.readAll();
        imgFile.close();
    }
}

void updateworker::isValidate(){
    //电话输入框只能输入11位数字
    QRegularExpression regExp( "0|[1-9]\\d{0,10}" );
    ui->phoneEdit->setValidator(new QRegularExpressionValidator(regExp,this));

    //名字输入7个字符最多
    QRegularExpression regExp2( "^.{0,7}$" );
    ui->nameEdit->setValidator(new QRegularExpressionValidator(regExp2,this));

}

void updateworker::on_perBox_currentTextChanged(const QString &arg1)
{
    permission = arg1;
}

void updateworker::on_updateWorkerButton_clicked()
{
    QString workerName = ui->nameEdit->text();
    QString phone = ui->phoneEdit->text();
    QString address = ui->addressEdit->text();
    QString per = permission;

    if( ui->nameEdit->text().isEmpty()){
        QMessageBox::warning(this, "警告", "名字不能为空!");
        ui->nameEdit->setFocus();
    }else if(ui->phoneEdit->text().isEmpty()){
        QMessageBox::warning(this, "警告", "电话不能为空!");
        ui->phoneEdit->setFocus();
    }else{
        updateWorker(GlobalData::workId,workerName,phone,address,imageData,per);

        this->close();
    }
}

void updateworker::updateWorker(int id,QString name,QString phone,QString address,QByteArray pic,QString permission){
    QSqlQuery query;
    query.prepare("UPDATE t_worker set name = :name,phone = :phone,address = :address,picture = :pic,permissions = :permission WHERE id = :id;");
    query.bindValue(":id", id);
    query.bindValue(":name", name);
    query.bindValue(":phone", phone);
    query.bindValue(":address", address);
    query.bindValue(":pic", pic);
    query.bindValue(":permission", permission);

    bool success = query.exec();
    if(success){
        GlobalData::action = UPDATE_WORKER;
        MainWindow m;
        m.updateLog(GlobalData::action);
        QMessageBox::information(this, "提示", "成功!");
        qDebug() << "Update statement executed successfully";
    } else {
        qDebug() << "Failed to execute update statement";
    }
}

QSS

本程序使用的样式文件,如何使用qss请参考其他博主的文章,网上教程很多也是比较简单的,相信大家很快能掌握

login.qss

QLabel#label{
background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #BAE4F2, stop:1 #14B9F3)
}

QLabel#label_2{
    background-color: transparent;
    color: rgb(255, 255, 255);
}

QWidget#Login{
background-color: rgb(255, 255, 255);
}

QLineEdit#usernameEdit,QLineEdit#usernameEditpasswordEdit{
    border: none;
    border-bottom: 1px solid black;
}

QPushButton#loginButton{
    color: rgb(255, 255, 255);
    font: 16pt "Microsoft YaHei UI";
    background-color: rgb(19, 114, 238);        
}

QPushButton#loginButton:hover{
    border: 4px solid black;
}

mainwindow.qss

QTableWidget{
    color:white;
    background:#0381a4;
    border:1px solid #242424;
    alternate-background-color:#9ee8f0;/*交错颜色*/
    gridline-color:#9ec4f0;
    font-size:20px;
}

QTableWidget::item:selected{
    color:#DCDCDC;
    background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #4daaec,stop:1 #1b5c7a);
}

/*
悬浮item*/
QTableWidget::item:hover{
    background:#e3edee;
}

/*表头*/
QHeaderView::section{
    text-align:center;
    background:#2eb5f4;
    padding:3px;
    margin:0px;
    color:white;
}

/*选中item*/
QTableWidget::item:selected{
    color:#4b76ee;
    background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #4daaec,stop:1 #27d9e5);
}

QMainWindow{
    background:white;
}

QLabel#backgroundlabel,#backgroundlabel_2,#backgroundlabel_3{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #0fcde6, stop:0.5 #4cd0a5, stop:1 #01bfdd);
}

QLabel#goodsPic,#workerPic{
    border:1px solid black;
}

QPushButton{
    background-color:white;
}

icon

这里把用到的一些图标分享一下

5.完整代码获取

链接:https://pan.baidu.com/s/1ieiftxQjI2GYzX-yLhk9VQ 
提取码:mjqx

  • 18
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Qt是一种跨平台的图形用户界面(GUI)开发框架,MySQL是一种常用的关系型数据库管理系统。结合使用QtMySQL可以实现一个通讯录管理系统。 首先,需要在Qt中建立一个用户界面,用于输入联系人的信息,包括姓名、电话号码、电子邮件等。用户可以通过界面的按钮添加、删除、编辑和搜索联系人。Qt提供了丰富的GUI控件,可以方便地设计和布局界面。 其次,需要建立一个MySQL数据库来存储联系人信息。可以在MySQL中创建一个名为"contacts"的表,表中包括列"ID"(作为主键)、"姓名"、"电话号码"、"电子邮件"等。通过Qt提供的MySQL驱动程序和相关函数,可以连接到数据库并执行SQL语句,实现数据的插入、删除、更新和查询等操作。 在Qt中,可以通过信号与槽机制来实现界面和数据库之间的交互。例如,当用户点击添加按钮时,界面会发出一个信号,槽函数会获取用户输入的联系人信息,然后将这些信息插入到MySQL表中。当用户点击查询按钮时,槽函数会根据用户输入的条件在MySQL表中查询联系人,并将结果显示在界面上。 除了基本的增删改查功能,还可以通过QtMySQL实现一些其他功能,如排序、过滤、导入导出等。在Qt中,还可以使用模型/视图(Model-View)架构,将数据库中的数据与界面进行解耦,使得程序的扩展和维护更加方便。 总之,使用QtMySQL可以快速开发一个功能完善的通讯录管理系统。通过Qt提供的丰富功能MySQL提供的高效数据存储和检索,用户可以方便地管理和查找自己的联系人信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值