qt人员管理模块(模块化程序)功能块复制直接使用不冲突

news2024/11/15 6:42:45

一、前言

 qt对人员管理部分个人总结的模块化程序,直接按照步骤复制粘贴程序,直接实现人员管理功能,无需花费脑筋在理清各个思路,适合快速编写组装程序

二、环境

windows

qt5.7

sqlite3

三、正文

思来想去大半天,不知道做成什么样的模块化能更好一些,想过方式一:直接通过接口调用外部界面,外部界面单独与数据库通讯交互,关闭界面之后回到主程序,这样优点就是程序无需特别多的嵌入,简单直白,缺点就是不容易统一样式和程序风格, 在不同程序结构下感觉会格格不入,所以本文最终选择了方式二:就是将所有使用的控件和代码调用方式开源,这样在写新的程序,在人员管理的位置,只要留好界面,然后放入模板的控件(3个按键,1个表格),在复制粘贴写好的程序就OK了。

话不多说直接看正文。

这里我跟着新建一个空程序,最后会把程序放到下载连接中,提供参考,正文中介绍的也很详细,跟着文章也会实现

1.数据库更改

数据库使用的是sqlite3,按下图创建两个表格,一个是所有用户信息表格,一个是上次登录信息表格

 2.更改pro文件

新建一个qt工程,在pro文件中添加如下信息

QT       += core gui sql

当然也可以多添加点库,因为都会用到

QT       += core gui axcontainer printsupport serialport sql
添加完pro文件对应就得引用相关头文件,这里建议使用一个通用.h文件用于方式公共信息,不用再每个文件中放入一堆头文件,这里我是用一个common.h的头文件,如下所示
#ifndef COMMON_H
#define COMMON_H
#include <QVector>
#include <QMap>
#include <QApplication>
#include <QMainWindow>
#include <QtSql>
#include <QSqlQuery>
#include <QSqlTableModel>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QDebug>
#include <QFile>
#include <QFileDialog>
#include <QMessageBox>
#include <QProcess>
#include <QPixmap>
#include <QPaintEvent>
#include <QPainter>
#include <windows.h>
#include <QScrollBar>
#include <QTableWidget>
#include <QListWidgetItem>
#include <QTimer>
#include <QTime>
#include <QSystemTrayIcon>
#include <QGridLayout>
#include <QPushButton>
#include <ActiveQt/QAxObject>   //Excel
#include <QDoubleSpinBox>
#include <QAbstractItemView>
#include <QCheckBox>

#define WINDOWS

extern QSqlDatabase db;
extern bool massage_dialog(int button_num,QString tile_text,QString massage_content,char ff);


class CommonHelper
{
public:
    static void setStyle(const QString &style) {
        QFile qss(style);
        qss.open(QFile::ReadOnly);
        qApp->setStyleSheet(qss.readAll());
        qss.close();
    }
};

//用户管理结构体
typedef struct
{
    QString now_username;//当前用户
    QString now_password;//当前密码
    bool now_root;//当前权限
    QString now_noted;//当前备注
    QStringList usernamelist;//用户列表
    QStringList userpswdlist;//用户密码
    QVector<bool> userroot;//用户权限
    QStringList usernote;//用户备注
}UserList;

#endif // COMMON_H

 3.更改main文件

之后就是写入口文件了,这里还没到正文主要部分,主要是先说明一下引用的相关环境内容,再main文件中我重定义了一个messagebox函数,可以自己控制消息提示框,当然不习惯的也可以用自己创建的界面代替,可以参照我之前的帖子,共创建了10余种不同功能的messagebox自定义界面。

这里我新建的数据库叫user.db       main.cpp如下

#include "common.h"
#include "login.h"
QSqlDatabase db;

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    ///更换主题
//    CommonHelper::setStyle(":/PIC/qss/white.qss");

    //打开数据库
    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(qApp->applicationDirPath()+"/user.db");
    db.open();

    login y;
    y.show();

    return a.exec();
}
bool massage_dialog(int button_num,QString tile_text,QString massage_content,char ff)
{
    int flag;
    QMessageBox *msgBox = new QMessageBox();
    QTimer::singleShot(15000,msgBox,SLOT(close())); //也可将accept改为close,定时关闭提示框,防止信号阻塞和假死
    /*调整提示框样式*/
    switch (button_num) {
    case 1:
        msgBox->addButton(QObject::tr("确定"), QMessageBox::YesRole);
        break;
    case 2:
        msgBox->addButton(QObject::tr("确定"), QMessageBox::YesRole);
        msgBox->addButton(QObject::tr("取消"), QMessageBox::NoRole);
        break;
    default:
        break;
    }
    msgBox->setWindowTitle(tile_text);
    msgBox->setText(massage_content);
    if(ff==0)msgBox->setIcon(QMessageBox::NoIcon);
    else if(ff==1)msgBox->setIcon(QMessageBox::Information);
    else if(ff==2)msgBox->setIcon(QMessageBox::Warning);
    else if(ff==3)msgBox->setIcon(QMessageBox::Critical);
    else if(ff==4)msgBox->setIcon(QMessageBox::Question);
    //msgBox->setStyleSheet("background-color:white");
    /*显示提示框*/
    flag = msgBox->exec();
    return flag;
}

4.登录界面login创建

登录界面login直接复制程序,ui就2个lineedit和2个按键以及两个checkbox,比较基础的人员管理,引用了common的人员部分结构体

 login.cpp

#include "login.h"
#include "ui_login.h"
#include "mainwindow.h"
UserList Data_user;//用户信息结构体
login::login(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::login)
{
    ui->setupUi(this);
//    this->setWindowFlags(Qt::WindowStaysOnTopHint);    //设置置顶
    this->setWindowModality(Qt::ApplicationModal);//设置一直保持在顶端,不可切换其他界面,除非被新界面带此属性覆盖
//    this->setWindowFlags(Qt::FramelessWindowHint);//设置界面无边框
//    this->setFocusPolicy(Qt::StrongFocus);//设置强焦点策略,这样输入法面板隐藏以后单击界面键盘隐藏
    this->setWindowFlags(Qt::Dialog);//取消窗口最大化最小化按钮

    ///获取数据库中用户信息
    QSqlQuery qry(db);
    if(qry.exec("select * from Sys_user")){//将所有用户信息遍历赋值到Data_user结构体中
          for(int i=0;qry.next()&&i<1000;i++){
              Data_user.usernamelist.append(qry.value(0).toString());//赋值用户账号
              Data_user.userpswdlist.append(qry.value(1).toString());//赋值用户密码
              Data_user.userroot.append(qry.value(2).toBool());//赋值当前学员列表(字符串未拆分)
              Data_user.usernote.append(qry.value(3).toString());//学员列表是否变更标志
          }
    }
    if(qry.exec("select * from Sys_userlast")&&qry.next()){//读取上次用户登录信息,自动赋值
        QString lastusername=qry.value(1).toString();//上次用户账号
        QString lastuserpswd=qry.value(2).toString();//上次用户密码
        bool savepassword_flag=qry.value(3).toBool();//是否保存密码
        bool autologin_flag=qry.value(4).toBool();//是否自动登录

        ui->username->setText(lastusername);//自动填入上次用户账号
        if(savepassword_flag)ui->userpassword->setText(lastuserpswd);//是否自动填入上次用户密码
        ui->checkBox1->setChecked(savepassword_flag);//自动填入上次用户是否保存密码信息
        ui->checkBox2->setChecked(autologin_flag);//自动填入上次用户是否自动登录
        if(autologin_flag==true){//自动登录上次用户
            QTimer::singleShot(10,this,SLOT(on_btn_login_clicked()));//延迟10ms在登录,否则登录界面在最前端,而不是菜单界面
        }
    }
}

login::~login()
{
    delete ui;
}
//记住密码
void login::on_checkBox1_clicked(bool checked)
{
    if(!checked)//如果取消记住密码,则取消自动登录选择
        ui->checkBox2->setChecked(false);
}
//自动登录
void login::on_checkBox2_clicked(bool checked)
{
    if(checked&&ui->checkBox1->isChecked());//只有在记住密码状态才可以选择自动登录
    else ui->checkBox2->setChecked(false);//否则不可选择自动登录
}
//登录
void login::on_btn_login_clicked()
{
    /*if(ui->username->text()=="admin"&&ui->userpassword->text()=="admin"){//判断超级账户
        Data_user.now_username=ui->username->text();//当前用户
        Data_user.now_password=ui->userpassword->text();//当前密码
        Data_user.now_root=1;
        Data_user.now_noted="超级管理员";
        menu *menu1 = new menu();
        menu1->show();
        menu1->setAttribute(Qt::WA_DeleteOnClose);//若是关闭界面,则彻底释放资源
        connect(this,SIGNAL(sendlogin(QString,QString,bool,QString)),menu1,SLOT(receivelogin(QString,QString,bool,QString)));
        emit sendlogin(Data_user.now_username,Data_user.now_password,Data_user.now_root,Data_user.now_noted);
    }
    else */if(Data_user.usernamelist.contains(ui->username->text())){//判断普通账户
        if(ui->userpassword->text()==Data_user.userpswdlist.at(Data_user.usernamelist.indexOf(ui->username->text()))){//判断密码
            //赋值登录信息到当前用户信息缓存
            Data_user.now_username=ui->username->text();//当前用户
            Data_user.now_password=ui->userpassword->text();//当前密码
            Data_user.now_root=Data_user.userroot.at(Data_user.usernamelist.indexOf(ui->username->text()));//当前登录者管理员状态
            Data_user.now_noted=Data_user.userroot.at(Data_user.usernamelist.indexOf(ui->username->text()));//当前登录者备注
            //存储当前登录界面配置信息到数据库
            QSqlQuery qry(db);//数据库保存
            qry.exec(QString("UPDATE Sys_userlast set username='%1',userpassword='%2',savepwd='%3',autologin='%4' where id = 1;").arg(ui->username->text()).arg(ui->userpassword->text()).arg(ui->checkBox1->isChecked()).arg(ui->checkBox2->isChecked()));
            //登录到主界面
            MainWindow *menu1 = new MainWindow();
            menu1->show();
            menu1->setAttribute(Qt::WA_DeleteOnClose);//若是关闭界面,则彻底释放资源
        }
        else{
            massage_dialog(1,"提示","密码错误!请重新输入!",1);
        }
    }
    else{
        massage_dialog(1,"提示","用户不存在!",1);
    }
}
//关机
void login::on_btn_pushout_clicked()
{
    this->close();
}

login.h

#ifndef LOGIN_H
#define LOGIN_H
#include "common.h"
extern UserList Data_user;
namespace Ui {
class login;
}
class login : public QWidget
{
    Q_OBJECT
public:
    explicit login(QWidget *parent = 0);
    ~login();
signals:
private slots:
    void on_checkBox1_clicked(bool checked);
    void on_checkBox2_clicked(bool checked);
    void on_btn_login_clicked();
    void on_btn_pushout_clicked();
private:
    Ui::login *ui;
};
#endif // LOGIN_H

这里还建立了一个picture的资源文件,添加了2张选择框样式图片

5.主界面mainwindow创建

在登录界面登录成功就是进入到主界面了,在主界面中只需创建3个按键和一个表格即可,前文的数据库调用,common.h文件的人员结构体,main文件的自定义messagebox都是铺垫,都是这里需要用到的资源,如果项目中包含这些,就不用从前再缕过来了,当然这是经历过几个程序叠加后的说,不然第一次用肯定不是按照我的思路,继续。

在mainwindow.ui文件中创建控件

 其中表格的样式表可以复制下面的

QTableView{/*设置常规*/
	alternate-background-color:rgb(255,255,255,20);
	background:black;
	color:white;
	gridline-color : rgb(120, 120, 120);
	font: 75 10pt "宋体";
}
QHeaderView::section{/*设置表头*/
	font: 75 16pt "宋体";
	color: white;
	background-color: rgb(42, 63, 22);
}

QTableView::Item:Selected{/*设置选中*/
	alternate-background-color:rgb(255,255,255,20);
	background:rgb(255,255,255,40);
	color: rgb(0, 0, 255);
}

QScrollBar:vertical {/*设置滚动条背景*/
      border: none;
 	  background-color: rgb(42,63,22);
      width: 3px;
  }
 QScrollBar::handle:vertical {/*设置滑动条*/
	 border: none;
     border-radius:2px;
      background: rgb(120, 120, 120);
  }
QScrollBar::sub-line:vertical {
      border: none;
      height: 0px;
      subcontrol-position: top;
      subcontrol-origin: margin;
  }
QScrollBar::add-line:vertical {
      border: none;
      height: 0px;
      subcontrol-position: bottom;
      subcontrol-origin: margin;
  }
  QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical {
	border:none;
      width: 0px;
      height: 0px;
  }
  QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
      background: none;
  }

控件名称tableWidget_user,btn_user_add,btn_user_change,btn_user_delete分别对应人员显示表格,人员添加按键,人员修改按键,人员删除按键。

mainwindow.h文件,这里增加了表格滑动功能,当表格放满一页后,通过触摸或者鼠标可以模拟手机滑动界面上下滑动

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "common.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
signals:
    //人员管理
    void sendtext(QString,QString,bool,QString,QStringList);//messagebox_user
protected:
    //表格滑动刷新
    bool eventFilter(QObject *obj, QEvent *event);
private slots:
    //人员管理
    void on_btn_user_add_clicked();//用户增加
    void on_btn_user_change_clicked();//用户修改
    void on_btn_user_delete_clicked();//用户删除
    void tableWidget_user_init(QTableWidget *tab,QVector<int> line,QStringList name,bool push);
    void tableWidget_user_refuse(QTableWidget *TableWidget);//更新用户信息
private:
    Ui::MainWindow *ui;
    QScrollBar *m_scrollBarV;//表格滚动实现
};
#endif // MAINWINDOW_H

mainwindow.cpp文件

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "login.h"
#include "messagebox/messagebox_user.h"

//风格:文字白色,图片选择样式切换
QString QCheckBoxstyle=
    "QCheckBox{color: rgb(255, 255, 255);background-color: rgb(0, 0, 0);}"
    "QCheckBox::indicator{background-color: rgba(255, 255, 255, 0);border: 0px solid #b1b1b1;width: 30px;height: 30px;}"
    "QCheckBox::indicator:unchecked {image:url(:/PIC/未选择.png);}"
    "QCheckBox::indicator:unchecked:hover {image:url(:/PIC/未选择.png);}"
    "QCheckBox::indicator:unchecked:pressed {image:url(:/PIC/未选择.png);}"
    "QCheckBox::indicator:checked {image:url(:/PIC/选择.png);}"
    "QCheckBox::indicator:checked:hover {image:url(:/PIC/选择.png);}"
    "QCheckBox::indicator:checked:pressed {image:url(:/PIC/选择.png);}";
QString btnwhite="color: rgb(255, 255, 255);";
QString btngreen="color: rgb(0, 255, 0);";
QString btnblue="color: rgb(20, 50, 255);";
QString btngray="color: rgb(160, 160, 160);";
QString btnstyle=
     "background-color: rgba(255, 255, 255, 0);"
     "border-right:0px solid #9eca56; "
     "border-bottom:0px solid #9eca56;"
     "border-left:0px solid #9eca56;"
     "border-top:0px solid #9eca56; "
     "font: 75 italic 12pt '宋体';"
     "text-decoration: underline;";

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

    this->setWindowModality(Qt::ApplicationModal);//设置一直保持在顶端,不可切换其他界面,除非被新界面带此属性覆盖
    this->setWindowFlags(Qt::Dialog);//取消窗口最大化最小化按钮


    //用户管理初始化
    QVector<int> table_line;
    table_line.append({140,600,400,100,300});//配置表格宽度5列
    QStringList table_title;
    table_title.append({"序号","账号(操作人员)","密码","管理员","备注"});//配置表格表头名称5列
    m_scrollBarV = ui->tableWidget_user->verticalScrollBar();//绑定表格滑动效//在表格第一次初始化前必须初始化一次,否则程序崩溃
    tableWidget_user_init(ui->tableWidget_user,table_line,table_title,true);//初始化表格表头
    tableWidget_user_refuse(ui->tableWidget_user);//更新全部用户信息
    connect(ui->tableWidget_user,&QTableWidget::cellPressed,[=](){//点击表格某行生效,当需要滑动时必定点击到表格某行。
        m_scrollBarV = ui->tableWidget_user->verticalScrollBar();//绑定表格滑动效
    });

}

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

/*****************************人员管理处理函数**********************************/
//用户增加
void MainWindow::on_btn_user_add_clicked()
{
    MessageBox_user * box = new MessageBox_user();
    box->show();
    box->setAttribute(Qt::WA_DeleteOnClose);//若是关闭界面,则彻底释放资源
    connect(this,SIGNAL(sendtext(QString,QString,bool,QString,QStringList)),box,SLOT(receivetext(QString,QString,bool,QString,QStringList)));
    emit sendtext("","",false,"",Data_user.usernamelist);
    connect(box,&MessageBox_user::sendtext,[=](QString res1,QString res2,bool res3,QString res4){
        qDebug()<<res1<<res2<<res3<<res4;
        QSqlQuery qry(db);//数据库保存
        qry.exec(QString("INSERT INTO Sys_user(name,password,root,note) VALUES ('%1','%2','%3','%4');").arg(res1).arg(res2).arg(res3).arg(res4));
        tableWidget_user_refuse(ui->tableWidget_user);//更新全部用户信息
    });
}
//用户修改
void MainWindow::on_btn_user_change_clicked()
{
    int checkid=0;
    QList<QCheckBox*> checkList = ui->tableWidget_user->findChildren<QCheckBox*>();
    for(int i=0;i<checkList.size();i++){//遍历寻找是否有选中
        if(checkList.at(i)->isChecked()){//如果找到选中,则跳出循环
            checkid=checkList.at(i)->objectName().replace("QCheckBox_user_","").toInt();//替换控件名称转换为表格所在的行
            break;//跳出寻找
        }
    }
    if(checkid>0){//有选中的行
        MessageBox_user * box = new MessageBox_user();
        box->show();
        box->setAttribute(Qt::WA_DeleteOnClose);//若是关闭界面,则彻底释放资源
        connect(this,SIGNAL(sendtext(QString,QString,bool,QString,QStringList)),box,SLOT(receivetext(QString,QString,bool,QString,QStringList)));
        QString change_username=Data_user.usernamelist.at(checkid-1);//赋值选中用户名称
        QString change_userpassword=Data_user.userpswdlist.at(checkid-1);//赋值选中用户密码
        bool change_userroot=Data_user.userroot.at(checkid-1);//赋值选中用户权限
        QString change_usernote=Data_user.usernote.at(checkid-1);//赋值选中用户备注
        emit sendtext(change_username,change_userpassword,change_userroot,change_usernote,Data_user.usernamelist);
        connect(box,&MessageBox_user::sendtext,[=](QString res1,QString res2,bool res3,QString res4){
//            qDebug()<<res1<<res2<<res3<<res4;
            //判断修改的用户是否为当前用户
            int err_flag=0;//错误编号
            if(change_username==Data_user.now_username){
                if(res3==0){
                    res3=1;
                    err_flag=1;//降低本身权限,可能导致没有账号能进入管理员系统
                }
                //赋值登录信息到当前用户信息缓存
                Data_user.now_username=res1;//当前用户
                Data_user.now_password=res2;//当前密码
                Data_user.now_root=res3;//赋值权限
                Data_user.now_noted=res4;//赋值备注
                //存储当前登录界面配置信息到数据库
                QSqlQuery qry(db);//数据库保存
                qry.exec(QString("UPDATE Sys_userlast set username='%1',userpassword='%2' where id = 1;").arg(res1).arg(res2));
                //刷新当前用户名称
                //ui->label_name->setText(QString("当前用户:%1").arg(Data_user.now_username));
            }
            QSqlQuery qry(db);//数据库保存
            qry.exec(QString("UPDATE Sys_user set name='%1',password='%2',root='%3' ,note='%4'where name = '%5';").arg(res1).arg(res2).arg(res3).arg(res4).arg(change_username));
            tableWidget_user_refuse(ui->tableWidget_user);//更新全部用户信息
            if(err_flag==1)
                massage_dialog(1,"提示","用户信息修改成功!\r\n(不可修改自身权限,已自动恢复)",1);
            else
                massage_dialog(1,"提示","用户信息修改成功!",1);
        });
    }
    else{
        massage_dialog(1,"提示","请选择要修改的用户列表序号!",1);
    }
}
//用户删除
void MainWindow::on_btn_user_delete_clicked()
{
    int checkid=0;
    QList<QCheckBox*> checkList = ui->tableWidget_user->findChildren<QCheckBox*>();
    for(int i=0;i<checkList.size();i++){//遍历寻找是否有选中
        if(checkList.at(i)->isChecked()){//如果找到选中,则跳出循环
            checkid=checkList.at(i)->objectName().replace("QCheckBox_user_","").toInt();//替换控件名称转换为表格所在的行
            break;//跳出寻找
        }
    }
    if(checkid>0){//有选中的行
        if(Data_user.usernamelist.at(checkid-1)==Data_user.now_username){
            massage_dialog(1,"提示","不可以删除当前登录用户!",1);
        }
        else{
            int res=massage_dialog(2,"提示",QString("是否确认删除用户%1").arg(Data_user.usernamelist.at(checkid-1)),4);
            if(res==0){//点击确认返回0,点击取消或关闭返回1
                QSqlQuery qry(db);
                qry.exec(QString("delete from Sys_user where name = '%1'").arg(Data_user.usernamelist.at(checkid-1)));
                qry.prepare("vacuum");//删除成功之后释放内存碎片
                qry.exec();
                tableWidget_user_refuse(ui->tableWidget_user);//更新全部用户信息
                massage_dialog(1,"提示","删除用户成功!",1);
            }
        }
    }
    else{
        massage_dialog(1,"提示","请选择要删除的用户列表序号!",1);
    }
}
//通用表格初始化函数,建立表格列,刷新表头和列宽
void MainWindow::tableWidget_user_init(QTableWidget *tab,QVector<int> line,QStringList name,bool push)
{
    tab->clearContents();//清空内容
    tab->verticalHeader()->setVisible(false);//去掉行序号
    tab->horizontalHeader()->setFixedHeight(40); //设置表头的高度
    tab->horizontalHeader()->setStretchLastSection(true);//设置表格是否充满,即行末不留空
    //tab->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed); //禁止鼠标拖放列宽度
    tab->horizontalHeader()->setFocusPolicy(Qt::NoFocus); //设置表头不可选
    tab->horizontalHeader()->setHighlightSections(false); //设置表头不可选//QTableWidget表头塌陷问题解决
    tab->setEditTriggers(QAbstractItemView::NoEditTriggers);//设置表格内容不可修改
    tab->setSelectionBehavior(QAbstractItemView::SelectRows);//设置选中就是一行选中
    tab->setSelectionMode(QAbstractItemView::SingleSelection);//设置只能选中一行
    tab->setFocusPolicy(Qt::NoFocus);//设置去掉选中虚线框
    //tab->setAlternatingRowColors(true);//设置表格颜色交替
    //表格滚动部分实现函数:初始化函数+以下俩函数+ (QObject *obj, QEvent *event)
    if(push)tab->viewport()->installEventFilter(this);//对此对象安装事件过滤器
    if(push)tab->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);//设置滚动模式按照像素滑动,做表格滑动时使用
    tab->setColumnCount(line.size());//设置列数量
    for(int i=0;i<line.size();i++)
        tab->setColumnWidth(i,line.at(i));
    tab->setHorizontalHeaderLabels(name);//设置table列表各项标题
    tab->setRowCount(0);
}
//更新用户信息
void MainWindow::tableWidget_user_refuse(QTableWidget *TableWidget)
{
    Data_user.usernamelist.clear();//清空用户账号
    Data_user.userpswdlist.clear();//清空用户密码
    Data_user.userroot.clear();//清空用户权限
    Data_user.usernote.clear();//清空用户备注
    QSqlQuery qry(db);
    if(qry.exec("select * from Sys_user")){
          for(int i=0;qry.next()&&i<1000;i++){
              Data_user.usernamelist.append(qry.value(0).toString());//赋值用户账号
              Data_user.userpswdlist.append(qry.value(1).toString());//赋值用户密码
              Data_user.userroot.append(qry.value(2).toBool());//赋值用户权限
              Data_user.usernote.append(qry.value(3).toString());//赋值用户备注
          }
    }
    TableWidget->clearContents();//清空内容
    TableWidget->setRowCount(Data_user.usernamelist.size());//设置表格行数
    //删除上次表格的复选框控件
    QList<QCheckBox*> checkList = TableWidget->findChildren<QCheckBox*>();
    for(int i=0;i<checkList.size();i++)delete checkList[i];
    //删除上次表格的按键控件
    QList<QPushButton*> btnList = TableWidget->findChildren<QPushButton*>();
    for(int i=0;i<btnList.size();i++)delete btnList[i];
    for(int i=0;i<Data_user.usernamelist.size();i++){  //刷新信号列表
        //表格插入复选框
        QCheckBox *lineid=new QCheckBox;
        lineid->setObjectName(tr("QCheckBox_user_%1").arg(i+1));
        TableWidget->setCellWidget(i,0,lineid);//插入按键到表格指定行列
        lineid->setText(QString("%1").arg(i+1,2,10,QChar('0')));//设置文本
        lineid->setStyleSheet(QCheckBoxstyle);//设置风格
        lineid->setFont(QFont("隶书", 12, QFont::Bold));//设置文字
        lineid->setAutoExclusive(true);//设置只有一个复选框可以选择,其他的自动失效
        TableWidget->setItem(i,1,new QTableWidgetItem(Data_user.usernamelist.at(i)));//更新账号
        TableWidget->item(i,1)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//数据居中
        TableWidget->setItem(i,2,new QTableWidgetItem(Data_user.userpswdlist.at(i)));//更新密码
        TableWidget->item(i,2)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//数据居中
        if(Data_user.userroot.at(i))
            TableWidget->setItem(i,3,new QTableWidgetItem("是"));//更新管理员
        else
            TableWidget->setItem(i,3,new QTableWidgetItem("否"));//更新管理员
        TableWidget->item(i,3)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//数据居中
        QPushButton *aaa=new QPushButton;
        aaa->setObjectName(tr("btn_page5_usertable_1_%1").arg(i+1));
        TableWidget->setCellWidget(i,4,aaa);//插入按键到表格指定行列
        aaa->setText("备注信息");//设置文本
        QString styles=btnwhite+btnstyle;styles.replace("12pt","16pt");
        aaa->setStyleSheet(styles);//设置风格,加大字号
        connect(aaa,&QPushButton::clicked,[=](){//绑定按键点击回调槽函数
            massage_dialog(1,"备注信息",Data_user.usernote.at(i),1);
        });
        TableWidget->setRowHeight(i,50);//设置行高
    }
//    TableWidget->resizeRowsToContents();//根据单元格内容自动换行
}

/*****************************通用处理函数**********************************/

//滑动表格实现函数
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
    static signed int press_y   = 0;
    static signed int move_y    = -1;
    static signed int release_y = 0;
    static QDateTime pressDateTime;
    static QPropertyAnimation *animation = new QPropertyAnimation();
//    qDebug()<<obj->objectName()<<event->type();
    if("qt_scrollarea_viewport" != obj->objectName())
        return false;
    int scrollV_max = m_scrollBarV->maximum();//获取当前滚动控件的最大进度条值
    int scrollV_min = m_scrollBarV->minimum();//获取当前滚动控件的最小进度条值,基本是0
#ifdef WINDOWS
    int global_y=QCursor::pos().y();//相对于正屏幕的y坐标,window下此方法即可获取
#else
    QMouseEvent *event1 = (QMouseEvent *)event;
    int global_y=event1->globalPos().y();//相对于正屏幕的y坐标,linux下用此方法获取
#endif
    //根据鼠标的动作——按下、放开、拖动,执行相应的操作
    if(event->type() == QEvent::MouseButtonPress){//记录按下的时间、坐标
        pressDateTime = QDateTime::currentDateTime();
        move_y  = global_y;
        press_y = move_y;
        animation->stop();
    }
    else if(event->type() == QEvent::MouseButtonRelease){//鼠标放开,根据鼠标拖动的垂直距离和持续时间,设置窗口滚动快慢程度和距离
        if(animation->targetObject() != m_scrollBarV){
            animation->setTargetObject(m_scrollBarV);
            animation->setPropertyName("value");
        }
        move_y = -1;
        release_y = global_y;
        QObject *parent_obj = obj->parent();
        if(parent_obj != 0 || parent_obj->inherits("QAbstractItemView"))
            QTimer::singleShot(150, (QAbstractItemView *)parent_obj, SLOT(clearSelection()));
        int endValue;
        int pageStep;
        if(release_y - press_y != 0 && qAbs(release_y - press_y) > 45){
            int mseconds = pressDateTime.msecsTo(QDateTime::currentDateTime());
            int limit = 440;
            pageStep = 240;//scrollBarV->pageStep();
            if(mseconds > limit)//滑动的时间大于某个值的时候,不再滚动(通过增加分母)
                mseconds = mseconds + (mseconds - limit) * 20;
            if(release_y - press_y > 0){
                endValue = m_scrollBarV->value()- pageStep * (200.0 / mseconds);//.0避免避免强制转换为整形
                if(scrollV_min > endValue)endValue = scrollV_min;
            }
            else if(release_y - press_y < 0){
                    endValue = m_scrollBarV->value() + pageStep * (200.0 / mseconds);
                    if(endValue > scrollV_max)
                        endValue = scrollV_max;
            }
            if(mseconds > limit)mseconds = 0;//滑动的时间大于某个值的时候,滚动距离变小,减小滑动的时间
            animation->setDuration(mseconds+550);
            animation->setEndValue(endValue);
            animation->setEasingCurve(QEasingCurve::OutQuad);
            animation->start();
            return true;
        }
    }
    else if(event->type() == QEvent::MouseMove && move_y >= 0){//窗口跟着鼠标移动
        int move_distance = global_y - move_y;
        int endValue = m_scrollBarV->value() - move_distance;
        if(scrollV_min > endValue)endValue = scrollV_min;
        if(endValue > scrollV_max)endValue = scrollV_max;
        m_scrollBarV->setValue(endValue);
        move_y = global_y;
    }
    return false;
}


这里引用了MessageBox_user这个类,用于与弹出界面交互,这个直接下载就行,开放一下就是如下:

messagebox_user.h

#ifndef MESSAGEBOX_USER_H
#define MESSAGEBOX_USER_H
#include <QDialog>
#include "common.h"

//The code from david!!!
#include <Windows.h>
#pragma comment(lib, "user32.lib")

namespace Ui {
class MessageBox_user;
}
class MessageBox_user : public QDialog
{
    Q_OBJECT
public:
    explicit MessageBox_user(QWidget *parent = 0);
    ~MessageBox_user();
protected:
    void paintEvent(QPaintEvent *paintevent);
signals:
    void sendtext(QString,QString,bool,QString);
private slots:
    void on_btn_sure_clicked();
    void on_btn_false_clicked();
    void receivetext(QString res1,QString res2,bool res3,QString res4,QStringList has);
    void closeEvent(QCloseEvent *event);//关闭程序
    void widgetShake(QWidget *pWidget, int nRange);//控件振动
private:
    Ui::MessageBox_user *ui;
    QPixmap pic;
    QStringList m_hascode;//已有的账号
};
#endif // MESSAGEBOX1_H

messagebox_user.cpp

#include "messagebox_user.h"
#include "ui_messagebox_user.h"

MessageBox_user::MessageBox_user(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::MessageBox_user)
{
    ui->setupUi(this);
    this->setWindowModality(Qt::ApplicationModal);//设置一直保持在顶端,不可切换其他界面,除非被新界面带此属性覆盖
    this->setWindowFlags(Qt::Dialog);//取消窗口最大化最小化按钮

    //如果设置背景为指定图片,打开下面两句
//    this->setWindowFlags(Qt::FramelessWindowHint);//设置窗体无边框
//    this->setAttribute(Qt::WA_TranslucentBackground);//设置背景透明
//    pic.load(tr(":/PIC/background/message5.png"));//设置背景

    ///设置按键调出键盘事件
    connect(ui->pushButton_keyboard,&QPushButton::clicked,[=](){
        //The code from david!!!
        PVOID OldValue;
        BOOL bRet = Wow64DisableWow64FsRedirection (&OldValue);
        QString csProcess="C:\\Windows\\System32\\osk.exe";
        QString params="";
        ShellExecute(NULL, L"open", (LPCWSTR)csProcess.utf16(), (LPCWSTR)params.utf16(), NULL, SW_SHOWNORMAL);
        if ( bRet ) Wow64RevertWow64FsRedirection(OldValue);
    });

    //倒计时关闭界面
//    for(int i=0;i<60;i++)
//        QTimer::singleShot(i*1000,this,[=](){ui->btn_false->setText(QString("取消(%1)").arg(59-i));});
//    QTimer::singleShot(60*1000,this,[=](){this->close();});
//    ui->btn_false->setFocus();//设置聚焦,作用你懂的
}
MessageBox_user::~MessageBox_user()
{
    delete ui;
}
void MessageBox_user::paintEvent(QPaintEvent *paintevent)
{
    paintevent->ignore();
    QPainter painter(this);
    painter.drawPixmap(0, 0, pic);//绘制图像
}
void MessageBox_user::on_btn_sure_clicked()
{
    if(ui->lineEdit_1->text().isEmpty()){
        ui->label_5->setText("不能为空");
        widgetShake(ui->label_5,5);
        ui->lineEdit_1->setFocus();
        return;
    }
    else if(m_hascode.contains(ui->lineEdit_1->text())){
        ui->label_5->setText("账号存在");
        widgetShake(ui->label_5,5);
        ui->lineEdit_1->setFocus();
        return;
    }
    else if(ui->lineEdit_1->text()=="不限"){
        ui->label_5->setText("禁用名称");
        widgetShake(ui->label_5,5);
        ui->lineEdit_1->setFocus();
        return;
    }
    else{
        ui->label_5->setText("");
    }
    if(ui->lineEdit_2->text().isEmpty()){
        ui->label_6->setText("不能为空");
        widgetShake(ui->label_6,5);
        ui->lineEdit_2->setFocus();
        return;
    }
    else{
        ui->label_6->setText("");
    }
    emit sendtext(ui->lineEdit_1->text(),ui->lineEdit_2->text(),ui->checkBox_gly->isChecked(),ui->textEdit->toPlainText());
    this->close();
}
void MessageBox_user::on_btn_false_clicked()
{ 
    this->close();
}
void MessageBox_user::receivetext(QString res1,QString res2,bool res3,QString res4,QStringList has)
{
    ui->lineEdit_1->setText(res1);
    ui->lineEdit_2->setText(res2);
    ui->checkBox_gly->setChecked(res3);
    ui->textEdit->setText(res4);
    m_hascode=has;
    m_hascode.removeAt(m_hascode.indexOf(res1));
//    qDebug()<<m_hascode;
    if(res1.isEmpty()&&res2.isEmpty())
        ui->lab_title->setText("人员增加");
    else
        ui->lab_title->setText("人员修改");
}
//振动效果
void MessageBox_user::widgetShake(QWidget *pWidget, int nRange)
{
    int nX = pWidget->x();
    int nY = pWidget->y();
    QPropertyAnimation *pAnimation = new QPropertyAnimation(pWidget,"geometry");
    pAnimation->setEasingCurve(QEasingCurve::InOutSine);
    pAnimation->setDuration(300);
    pAnimation->setStartValue(QRect(QPoint(nX,nY),pWidget->size()));

    int nShakeCount = 20; //抖动次数
    double nStep = 1.0/nShakeCount;
    for(int i = 1; i < nShakeCount; i++){
        nRange = i&1 ? -nRange : nRange;
        pAnimation->setKeyValueAt(nStep*i,QRect(QPoint(nX + nRange,nY),pWidget->size()));
    }

    pAnimation->setEndValue(QRect(QPoint(nX,nY),pWidget->size()));
    pAnimation->start(QAbstractAnimation::DeleteWhenStopped);
}
void MessageBox_user::closeEvent(QCloseEvent *event)
{
    HWND appWnd;
    appWnd = ::FindWindow(L"OSKMainClass", NULL);
    if (appWnd){
       SendMessage(appWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
    }
}

messagebox_user.ui

 最后编译运行即可,总结前文,主要就是准备阶段连套的稍微多了一些,这个基本每个程序都是需要的,都这么写就行,人员管理部分按照上面头文件和源文件两大块直接复制粘贴,创建4个控件放在界面中,就实现功能了,妈妈再也不用担心我写程序在人员管理这块功能浪费时间了。

实现效果:

未点击自动登录下,点击记住密码,自动刷新上次账号密码,不登陆

点击自动登录,和记住密码,下次打开软件自动登录到mainwindow界面

取消记住密码自动取消自动登录

登录后自动刷新数据库中存储的所有人员信息

点击人员添加界面弹出新建人员提示框

 输入信息重复或输错信息会有提示

 

录入成功后自动更新表格,可以点击序号列进行人员修改

 

 修改当前登录人员会自动更新记录的上次登录信息,下次还是自动登录当前人员

删除人员具有消息选择框提示选择是否删除,15秒无操作自动关闭界面,只有点击确认才删除

动态演示如下:

 

四、结语

本文例程下载链接

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

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

相关文章

JS快速入门

一、JS介绍 JavaScript &#xff08;简称JS&#xff09;&#xff0c;是一门跨平台、面向对象的脚本语言&#xff08;弱类型语言&#xff09;&#xff0c;而Java语言也是跨平台的、面向对象的语言&#xff0c;只不过Java是编译语言&#xff0c;是需要编译成字节码文件才能运行的…

自定义RBAC(1)

您好&#xff0c;我是湘王&#xff0c;这是我的CSDN博客&#xff0c;欢迎您来&#xff0c;欢迎您再来&#xff5e; 在对Spring Security稍做了解之后&#xff0c;可以知道&#xff0c;Spring Security其实只是一个实现认证授权的框架&#xff0c;封装了很多实现细节。但也有一些…

【Linux网络编程】服务端编程初体验

文章目录前言服务端是啥、有什么特点核心函数socket的简介服务器编程客户端代码The End前言 在上节课(Linux网络编程初体验)中我们实现了连接bilibili的功能&#xff0c;并获取其html源码 如图所示. 今天我们要自己编写个服务端来服务我们的客户端 提示&#xff1a;以下是本篇…

SGI STL 二级空间配置源码刨析

文章目录内存分配第二级配置器空闲链表的设计内存申请代码内存释放代码注意内存分配 当我们new一个对象时&#xff0c;实际做了两件事情&#xff1a; 使用malloc申请了一块内存。执行构造函数。 在SGI中&#xff0c;这两步独立出了两个函数&#xff1a;allocate申请内存&…

年产20吨鸡枞菌产品的生产工艺设计(lunwen+课题登记表+cad图纸)

目录 摘 要 1 Abstract 2 一、设计任务和内容 4 1.1 设计题目 4 1.2 设计原始数据 4 二、设计说明 5 2.1 全厂总平面布置 5 2.1.1 原料厂及堆场 5 2.1.2 生产区 5 2.1.3 厂前区 6 2.1.4 动力区 6 2.1.5 辅助车间 6 2.1.6 仓库区 6 2.2 三废的处理及回收 6 2.3 车间布置说明 6 三…

Request和Response基础知识入门

文章目录1&#xff0c;Request和Response的概述2&#xff0c;Request对象2.1 Request继承体系2.2 Request获取请求数据2.2.1 获取请求行数据2.2.2 获取请求头数据2.2.3 获取请求体数据2.2.4 获取请求参数的通用方式2.3 IDEA快速创建Servlet2.4 请求参数中文乱码问题2.4.1 POST请…

【Unity3D】绘制物体表面三角形网格

1 仅绘制三角形网格 1&#xff09;创建游戏对象 创建一个空对象&#xff0c;重命名为 Grid&#xff0c;并在其下添加需要绘制网格的对象&#xff0c;如下&#xff1a; 场景显示如下&#xff1a; 2&#xff09;添加脚本组件 GridController.cs using System; using UnityEngin…

JavaWeb_第4章_RequestResponse

JavaWeb_第4章_Request&Response 文章目录JavaWeb_第4章_Request&Response1&#xff0c;Request和Response的概述2&#xff0c;Request对象2.1 Request继承体系2.2 Request获取请求数据2.2.1 获取请求行数据2.2.2 获取请求头数据2.2.3 获取请求体数据2.2.4 获取请求参数…

【ceph】分布式存储ceph

1 块存储&#xff0c;文件存储&#xff0c;对象存储 1.1 简介 文件存储&#xff1a;分层次存储&#xff0c;文件存储在文件夹中&#xff1b;访问文件时系统需要知道文件所在的路径。 举例&#xff1a;企业部门之间运用网络存储器&#xff08;NAS&#xff09;进行文件共享。 …

把握出租车行驶的数据脉搏 :出租车轨迹数据给你答案!

城市化带来的道路拥堵、出行耗时长等交通问题给交管部门带来了巨大的挑战。 ▼ 通过安装在出租车上的GPS设备&#xff0c;可以采集到大量的轨迹数据&#xff0c;从而帮助我们分析人们出行信息&#xff0c;达到优化交通的目的。 最近我们被客户要求撰写关于出租车行驶的研究报…

一次性分清zip、gzip、bzip2、tar命令

文章目录归类zip与unzip命令tar命令使用方式zipunzipgzipgunzipbzip2bunzip2tar归类 我们把这几个命令归类为几种能力&#xff0c;一个是解压缩能力一个是打拆包能力。 我这里打包的意思是不使用压缩算法对文件进行压缩&#xff0c;只是简单的把多个文件归档为一个文件。而拆包…

Qt OpenGL(二十五)——Qt OpenGL 核心模式-Qt封装的函数实现彩色三角形

Qt OpenGL(二十五)——Qt OpenGL 核心模式-Qt封装的函数实现彩色三角形 上一篇文章我们绘制了彩色的三角形,接下来其实就应该是让这个三角形旋转起来了,但是,旋转起来之前,还是想通过Qt自己的封装类实现彩色的三角形,并且让他旋转起来。 这才我(冯一川)是写这个系列…

编程之美4 Nim游戏

Tag&#xff1a;贪心&#xff1b;动态规划 题目 N块石头排成一行&#xff0c;每块石头有各自固定的位置。两个玩家依次取石头&#xff0c;每个玩家每次可以取其中任意一块石头&#xff0c;或者相邻的两块石头&#xff0c;石头在游戏过程中不能移位&#xff08;即编号不会改变…

在ASF中使用On Demand生产DEM等产品时使用不同参考DEM的区别

在ASF中使用On Dmand生产DEM等产品时使用不同参考DEM 主要有两种DEM&#xff0c;分别是SRTM和COP-DEM&#xff08;GLO-30&#xff09; 当我们添加Dmand进程之后&#xff0c;点击On Demand Queue 然后进入On Demand界面&#xff08;如下图所示&#xff09; 在Processing Op…

MySQL主从复制介绍及实操演示

1. 基本概念 MySQL主从复制的主要效果简单来说是将两个单独的数据库服务器关联起来&#xff0c;对于主机&#xff08;Master&#xff09;以及从机&#xff08;Slave&#xff09;&#xff0c;从机的数据会伴随着主机数据的变化而同步 2. 主从复制作用 可以解决单个MySQL数据库…

leetcode 63. 不同路径 II

文章目录题目思考代码和注释总结题目 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑…

Android WorkManager使用介绍

一、引言 WorkManager 是google提供的异步执行任务的管理框架&#xff0c;是 Android Jetpack 的一部分&#xff0c;会根据手机的API版本和应用程序的状态来选择适当的方式执行任务。   在后台执行任务的需求是非常常见的&#xff0c;Android也提供了多种解决方案&#xff0c…

高阶数据结构:并查集

本篇主要是介绍并查集的内容&#xff1a;所谓并查集就是一种描述不相交集合的数据结构&#xff0c;即若一个问题涉及多个元素&#xff0c;它们可以划分到不同集合&#xff0c;同属一个集合内的元素等价&#xff0c;不同集合内的元素不等价。 文章目录 一、并查集原理二、并查集…

Prophet在R语言中进行时间序列数据预测

您将学习如何使用Prophet&#xff08;在R中&#xff09;解决一个常见问题&#xff1a;预测公司明年的每日订单。 最近我们被客户要求撰写关于时间序列的研究报告&#xff0c;包括一些图形和统计输出。 数据准备与探索 Prophet最适合每日数据以及至少一年的历史数据。 我们将…

Ansible

Ansible是什么&#xff1f; Ansible是一个基于eythn开发的配置管理和应用部署工具&#xff0c;现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点&#xff0c;Pbet和Saltstack能实现的功能&#xff0c;As;ble基本上都可以实现。Ansible能批量配置、部署、管理上…