一、前言

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 WINDOWSextern 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: 16pt "宋体";
}
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);elsemassage_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,点击取消或关闭返回1QSqlQuery 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("是"));//更新管理员elseTableWidget->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);//设置风格,加大字号//方式二aaa->setStyleSheet("font: 16pt ""黑体"";background-color: #000000;color: rgb(202, 234, 206);border-radius:10px;");//设置风格aaa->setMinimumSize(140,45);//设置按键控件最小尺寸aaa->setIcon(QIcon(":/PIC/查看1.png"));//设置图标aaa->setIconSize(QSize(40,40));//设置图标尺寸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 WINDOWSint global_y=QCursor::pos().y();//相对于正屏幕的y坐标,window下此方法即可获取
#elseQMouseEvent *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("人员增加");elseui->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秒无操作自动关闭界面,只有点击确认才删除

动态演示如下:


20230203更新

更改查询表格首列QCheckBox控件不居中问题,增加layout和widget

新刷新表格函数如下

//更新用户信息
void people::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<QWidget*> widgetList = TableWidget->findChildren<QWidget*>();for(int i=0;i<widgetList.size();i++){if(widgetList.at(i)->objectName().contains("widget_usertable_"))//判断是表格创建控件,才刷新delete widgetList[i];//删除表格中新建的widget,根据object命名,避免错误删除其他widget}//删除上次表格的按键控件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++){  //刷新信号列表//创建水平布局QHBoxLayout *vLayout = new QHBoxLayout(this);//创建布局,布局不需要单独删除,会随着widget删除vLayout->setContentsMargins(30, 2, 10, 2);// 设置外间距left,top,right,bottomvLayout->setSpacing(10);//设置内间距//创建widget放入单元格中,在widget里放入其他控件QWidget *widget = new QWidget(this);widget->setObjectName(tr("widget_usertable_%1").arg(i+1));widget->setStyleSheet("background-color:rgb(0,0,0,0)");//表格插入复选框QCheckBox *lineid=new QCheckBox;lineid->setObjectName(tr("QCheckBox_user_%1").arg(i+1));lineid->setText(QString("%1").arg(i+1,2,10,QChar('0')));//设置文本lineid->setStyleSheet(QCheckBoxstyle);//设置风格lineid->setFont(QFont("隶书", 20, QFont::Bold));//设置文字lineid->setAutoExclusive(true);//设置只有一个复选框可以选择,其他的自动失效vLayout->addWidget(lineid);//将复选框放入布局中widget->setLayout(vLayout);//将布局放入widget中TableWidget->setCellWidget(i,0,widget);//插入按键到表格指定行列widget->show();//显示widgetTableWidget->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("是"));//更新管理员elseTableWidget->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);//设置风格,加大字号//方式二aaa->setStyleSheet("font: 16pt ""黑体"";background-color: rgb(202, 234, 206,0);color: rgb(255, 255, 255);text-decoration: underline;");//设置风格aaa->setMinimumSize(140,45);//设置按键控件最小尺寸aaa->setIcon(QIcon(":/icon/搜索.png"));//设置图标aaa->setIconSize(QSize(40,40));//设置图标尺寸connect(aaa,&QPushButton::clicked,[=](){//绑定按键点击回调槽函数massage_dialog(1,"备注信息",Data_user.usernote.at(i),1);});TableWidget->setRowHeight(i,60);//设置行高}
//    TableWidget->resizeRowsToContents();//根据单元格内容自动换行
}

效果:

修改了表头和网格线颜色,样式表修改

QTableView{gridline-color : rgb(120, 120, 120);
}
QHeaderView::section{/*设置表头*/font: 75 22pt "黑体";background-color: rgb(55, 156, 212);color: rgb(255, 255, 255);
}

四、结语

本文例程下载链接

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

  1. Unity程序基础框架__音效管理模块

    音效管理模块 作用:统一管理音乐音效相关 以前处理音效播放的时候就是哪儿需要播放音效就在哪儿去添加相关的代码段,弄得项目代码不简洁,也很冗杂,为了解决这个问题,整理了一个音效管理的模块,我们在哪儿需要 ...

  2. java毕业设计——基于java+JSP+sqlserver的Smart系统-题库及试卷管理模块设计与实现(毕业论文+程序源码)——学生信息管理系统模板2

    基于java+JSP+sqlserver的Smart系统-题库及试卷管理模块设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+JSP+sqlserver的Smart系统-题库及试卷 ...

  3. java二分查找宿舍管理_1、任务:为宿舍管理人员编写一个宿舍管理查询软件, 程序设计要求: (1)采用交互工作方式...

    1.任务:为宿舍管理人员编写一个宿舍管理查询软件, 程序设计要求: (1)采用交互工作方式 2016-08-22 0 0 0 暂无评分 其他 1 积分下载 如何获取积分? 1.任务:为宿舍管理人员编写 ...

  4. 公众号管理模块-DouPHP模块化企业网站管理系统v1.6

    简介: DouPHP是一款轻量级企业网站管理系统,基于PHP+MYSQL架构的,包含"手机版"."公众号管理模块"."小程序",可以使用它快 ...

  5. 使用连接管理器出现“安装程序无法复制文件”错误的解决方法

    使用连接管理器出现"安装程序无法复制文件"错误的解决方法 在我们的企业中,使用"连接管理器"创建的***客户端连接程序,在运行安装程序的时候,有的机器出现&qu ...

  6. Unity程序开发框架——UI管理模块

    UI基类BasePanel负责帮助我门通过代码快速的找到所有的子控件,方便我们在子类中处理逻辑,节约找控件的工作量. public class BasePanel : MonoBehaviour {/ ...

  7. [Java开发]搭建人力资源管理系统——简历管理模块(附带下载链接)

    最近一位老哥让我给他的公司开发一套人力资源管理系统,并详细描述了这个系统的一些功能,我也查找了一些人力资源的资料.因为跟老哥关系不错,就答应了他.大家都知道,人力资源管理就是管人的,从给公司开始投递简 ...

  8. 基于区块链的Smart系统-题库及试卷管理模块的设计与开发

      1引言 1.1课题背景 随着网络技术的飞速发展,现在很多国外的大学和社会其他部门都已经开设了远程教育,通过计算机网络实现异地教育和培训.现在,计算机硬件技术的发展已经达到了相当高的水平.但是,远程 ...

  9. 70-项目实战后续(课程管理模块)

    项目实战后续(课程管理模块) 项目介绍: 前面我们完成了初步的项目,接下来实现更高等级的作用(基于框架的项目编写) 页面原型展示: 技术选型: 前端技术选型: 后端技术选型: 项目开发环境 : 开发工 ...

最新文章

  1. JDK8 HashMap--removeNode()移除节点方法
  2. HTML5中各种标签总结(超链接标签、锚点设置)
  3. ajax速度axio速度,[转]Ajax Fetch Axios之间的详细区别以及优缺点
  4. java创建方法并引用_java – 创建非捕获方法引用,它将调用超类方法
  5. 程序员经常看的开源月刊《HelloGitHub》第 57 期
  6. 如何修复GitKraken Inotify Limit Error\idea erro - 升级Ubuntu / Linux inotify限制
  7. 手动实现读写锁(线程级)
  8. 2021-08-18我的第一篇博客——STM32单片机的开发环境Keil5(MDK)的安装与破解
  9. VS语音信号处理(1) C语言读取WAV语音文件文件头数据
  10. k近邻算法_面试|k近邻(KNN)算法与k均值(kmeans)聚类算法有何不同?
  11. microsoft edge怎么截长图_苹果12怎么截图截长屏 iphone 12截长图快捷键方法介绍
  12. 爱奇艺影业,你明天还为传统电影业打工吗?
  13. Python分析《三国演义》中的社交网络
  14. 第五代人工智能计算机英语,计算机专业英语——关于第五代计算机
  15. Java如何创建支付接口
  16. RedHatEnterpriseLinux [RHEL]7.0——操作系统下载地址
  17. 美团和大众点评合并后,两家的技术大牛们该咋办?
  18. Zstack home 1.2.2a兼容对接ZHA标准设备和2.5.1a私有设备
  19. 维昇药业冲刺港交所上市:暂未实现商业化,2021年亏损约4.9亿元
  20. 平衡小车控制板(开源PCB、源码、3d模型)

热门文章

  1. weblogic BEA-000362问题
  2. Tableau 八、数据分层、数据分组、数据集
  3. 建行找不到服务器或DNS错误,建行浏览器打不开,提示域名解析错误,代码105,怎么解决?谢谢...
  4. maven查找依赖的方法
  5. RC延时电路的 时间常数 和 延时时间(电压达到时间)和电容充放电时间计算和选取
  6. linux怎么进入绘图模式,Linux 绘图工具
  7. linux 实验感悟_linux实训心得_linux实习心得体会范文
  8. 《量子信息与量子计算简明教程》第三章·量子纠缠状态及其应用 (上)
  9. 安卓java 模拟点击类_Android模拟用户点击的实现方法
  10. discuz当qq绑定超过5个网址时 如何解除绑定qq