当前位置: 首页 > news >正文

QT肝8天14--编辑用户

1、编辑用户实现思路 

1.弹出一个对话框
2.在对话框中,应该展示当前编辑的数据---带上条件去查询下数据库
3.绑定到对话框
4. 提供确认和取消的按钮
5.点击确认---把修改后的数据更新到数据库中去;

2、一步一步抓落实

1、添加编辑页面文件

2、编辑按钮信号和槽函数

#include "peoplewin.h"
#include "sqlite3/sqlite3db.h"
#include "ui_peoplewin.h"
#include <QGraphicsDropShadowEffect>
#include <QMessageBox>
#include <qgridlayout.h>PeopleWin::PeopleWin(QWidget *parent): QWidget(parent), ui(new Ui::PeopleWin)
{ui->setupUi(this);pageWidget = new PageWidget();//创建分页控件this->layout()->addWidget(pageWidget);//添加到当前布局initUI();//初始化UI界面initOperators(1);//初始化列表ui->lineEdit->setPlaceholderText("请输入用户名或姓名");  //设置搜索框提示信息// 绑定槽函数----点击了分页控件的中的页码后,触发信号,触发当前页重新加载数据connect(pageWidget, SIGNAL(currentPageChanged(int)), this,SLOT(initOperators(int)));
}PeopleWin::~PeopleWin()
{delete ui;
}//初始化
void PeopleWin::initUI()
{// 设置图标this->setWindowIcon(QIcon(":/img/zhaoxi.png"));// 布局Qt::WindowFlags flags = this->windowFlags();flags |= Qt::FramelessWindowHint;       // //隐藏标题栏flags &= ~Qt::WindowMinMaxButtonsHint;  // 隐藏最小最大化按钮flags &= ~Qt::WindowCloseButtonHint;    // 隐藏关闭按钮this->setWindowFlags(flags);
}//初始化数据
void PeopleWin::initOperators(int pageIndex)
{Sqlite3Db db;OperatorInfoList operatorinfs;//分页有关变量int pagesize=5;//每页10条int pagecount=0;//共10页QString searchString=ui->lineEdit->text().trimmed();//去掉前后空格if(db.selectOperators(searchString,pageIndex,pagesize,pagecount,operatorinfs)){BindOperatorList(operatorinfs);//operatorinfs就是查到的列表pageWidget->setCurrentPage(pageIndex);pageWidget->setMaxPage(pagecount);}
}//添加数据到数据库中去
void PeopleWin::onAddOperator(OperatorInfo &opt)
{Sqlite3Db db;bool ret=db.insertOperator(opt);if(ret){initOperators(1);//重新加载m_addOperator->m_basewin->close();//关闭窗体}
}//删除操作
void PeopleWin::onDeleteOperator(qint64 id)
{Sqlite3Db db;bool ret=db.deleteOperator(id);if(ret){initOperators(1);//重新加载QMessageBox::information(this,"信息提示","删除成功.");}else{QMessageBox::critical(this, "信息", "删除失败!");}
}//编辑操作
void PeopleWin::onUpdateOperator(qint64 id)
{Sqlite3Db db;OperatorInfo info;if (db.selectOperatorsById(id, info)) {//根据id查询数据// 弹出对话框if (m_editOperator != nullptr) {delete m_editOperator;}m_editOperator = new EditOperator(this);qRegisterMetaType<OperatorInfo>("OperatorInfo");m_editOperator->showWinOperator(info);// 绑定信号和槽---注意:绑定信号槽--参数,定义和这里的绑定必须完全匹配QObject::connect(m_editOperator, SIGNAL(sigEditOperator(OperatorInfo &)),this, SLOT(onEditOperator(OperatorInfo &)));} else {QMessageBox::critical(this, "信息", "编辑失败");}
}// 执行更新
void PeopleWin::onEditOperator(OperatorInfo &opt) {// 更新数据库Sqlite3Db db;if (db.updateOperator(opt)) {m_editOperator->m_baseWind->close();initOperators(1);// 重新刷新数据QMessageBox::information(this, "信息", "更新成功!");} else {QMessageBox::critical(this, "信息", "更新失败");}
}//绑定数据到列表
void PeopleWin::BindOperatorList(OperatorInfoList operators)
{ui->tableWidget->setRowCount(0);ui->tableWidget->verticalHeader()->hide();  // 默认的tablewidget 会有一列,这一列需要隐藏//设置标题栏的扩展模式为平铺ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);ui->tableWidget->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);// 获取当前程序所在绝对路径QString basePath = QCoreApplication::applicationDirPath();//循环绑定每个对象到列表for(int i=0;i<operators.size();i++){ui->tableWidget->setRowCount(i+1);ui->tableWidget->setRowHeight(i,40);//行高OperatorInfo opt=operators.at(i);//获取循环位置的对象// //第1列,绑定序号QTableWidgetItem *item=new QTableWidgetItem(QString::number(i+1));//创建一行记录item->setTextAlignment(Qt::AlignCenter);//对齐方式ui->tableWidget->setItem(i,0,item);//添加一行项目//第2列,绑定头像, 展示头像的时候,绘制一个图片QString fullimagePath = basePath + "/" + opt.icon; // 拼装图片所在的完整路径//qDebug() << fullimagePath;// 展示头像的时候,绘制一个图片QPixmap pIcon;pIcon.load(fullimagePath);pIcon = pIcon.scaled(24, 24);auto picLabel = new QLabel;picLabel->setPixmap(pIcon);picLabel->resize(24, 24);auto cellWidget = new QWidget;auto layout = new QHBoxLayout;layout->setAlignment(Qt::AlignCenter);layout->addWidget(picLabel);cellWidget->setLayout(layout);ui->tableWidget->setCellWidget(i, 1, cellWidget);ui->tableWidget->setColumnWidth(1, 200);//第3列, 绑定姓名item = new QTableWidgetItem(QString("%1").arg(opt.name));item->setTextAlignment(Qt::AlignCenter);ui->tableWidget->setItem(i, 2, item);//第4列, 绑定用户名item = new QTableWidgetItem(QString("%1").arg(opt.username));item->setTextAlignment(Qt::AlignCenter);ui->tableWidget->setItem(i, 3, item);//第5列, 绑定地址item = new QTableWidgetItem(QString("%1").arg(opt.addr));item->setTextAlignment(Qt::AlignCenter);ui->tableWidget->setItem(i, 4, item);// 第6列,绑定性别QString gen;if (opt.gender == 0) {gen = "男";} else {gen = "女";}item = new QTableWidgetItem(gen);item->setTextAlignment(Qt::AlignCenter);ui->tableWidget->setItem(i, 5, item);cellWidget = new QWidget;layout = new QHBoxLayout;layout->setAlignment(Qt::AlignCenter);//第7列, 绑定电话item = new QTableWidgetItem(QString("%1").arg(opt.phoneNo));item->setTextAlignment(Qt::AlignCenter);ui->tableWidget->setItem(i, 6, item);//第7列,操作类型//编辑按钮QPushButton *p1=new QPushButton("编辑");//指定样式p1->setStyleSheet("QPushButton{color:#409EFE;background: transparent;}""QPushButton:hover{color:#409EFE;background: ""transparent; text-decoration:underline;}");layout->addWidget(p1);//绑定事件,信号和槽函数,匿名绑定QObject::connect(p1,&QPushButton::clicked,[=]{//QMessageBox::information(this,"信息提示","编辑系统."); onUpdateOperator(opt.id);});//删除按钮QPushButton *p2=new QPushButton("删除");p2->setStyleSheet("QPushButton{color:#409EFE;background: transparent;}""QPushButton:hover{color:red;background: ""transparent; text-decoration:underline;}");layout->addWidget(p2);//绑定事件,信号和槽函数,匿名绑定QObject::connect(p2,&QPushButton::clicked,[=]{// QMessageBox::information(this,"信息提示","删除系统.");//删除前的提示确认框int index = QMessageBox::warning(this, "删除?", "确认删除【" + opt.username + "】数据吗?", "确认", "取消");if (index == 1) {return;}onDeleteOperator(opt.id);});cellWidget->setLayout(layout);layout->setContentsMargins(0,0,0,0);ui->tableWidget->setCellWidget(i, 7, cellWidget);}
}//刷新
void PeopleWin::on_btnSearch_clicked()
{initOperators(1);//重新加载
}//新增人员:1、弹出对话框 2、提供输入信息 3、保存到db
void PeopleWin::on_addButton_clicked()
{if( m_addOperator== nullptr){m_addOperator=new AddOperator(this);//创建窗体对象qRegisterMetaType<OperatorInfo>("OperatorInfo");// 绑定信号sigAddOperator和槽函数onAddOperatorconnect(m_addOperator,SIGNAL(sigAddOperator(OperatorInfo &)),this,SLOT(onAddOperator(OperatorInfo &)));}else{m_addOperator->m_basewin->show();}
}

3、数据库处理逻辑

4、加载用户信息

5、保存用户信息

#include "editoperator.h"
#include "ui_editoperator.h"EditOperator::EditOperator(QWidget *parent): QWidget(parent), ui(new Ui::EditOperator)
{ui->setupUi(this);ui->HeIdlineEdit->hide();  // 设置隐藏域,用来保存每次修改数据的时候,给定的记录id//  创建基类窗口baseWin的实例if (m_baseWind == nullptr) {m_baseWind = new BaseWin(parent);}m_baseWind->setContentWidget(this);  // 把当前内容嵌套到基类窗口的内容区域m_baseWind->setTitle("修改人员");m_baseWind->resize(600, 350);m_baseWind->show();//设置编辑窗体的2个按钮QPushButton *b1 = m_baseWind->getButton();if (b1) {b1->setText("保存");// 给按钮绑定点击触发槽函数QObject::connect(b1, &QPushButton::clicked, this, &EditOperator::OnSaveOperator);}QPushButton *b2 = m_baseWind->getButton2();if (b2) {b2->setText("取消");//匿名绑定信号和槽函数QObject::connect(b2, &QPushButton::clicked, [=] { m_baseWind->close(); });}
}// 点击保存按钮后的确认操作
void EditOperator::OnSaveOperator() {OperatorInfo opt;opt.id = ui->HeIdlineEdit->text().toULongLong();opt.username = ui->usernameLineEdit->text();opt.name = ui->nameLineEdit->text();opt.gender = ui->maleRadioButton->isChecked() ? 0 : 1;opt.addr = ui->addrLineEdit->toPlainText();opt.phoneNo = ui->phoneNoLineEdit->text();opt.icon = "files/zhaoxi.png";emit sigEditOperator(opt);  // 触发信号,去添加数据
}// 加载显示用户信息
void EditOperator::showWinOperator(OperatorInfo opt) {ui->usernameLineEdit->setText(opt.username);ui->nameLineEdit->setText(opt.name);if (opt.gender == 0) {ui->maleRadioButton->setChecked(true);//男性选中} else {ui->femaleRadioButton->setChecked(true);//女性选中}ui->addrLineEdit->setPlainText(opt.addr);ui->phoneNoLineEdit->setText(opt.phoneNo);ui->HeIdlineEdit->setText(QString::number(opt.id));
}EditOperator::~EditOperator()
{delete ui;
}

#include "sqlite3db.h"
#include <QDebug>
#include <QtSql>
#include <QSqlDatabase>
#include <QSqlQuery>Sqlite3Db::Sqlite3Db() {}// Qt访问Sqlite的步骤:
// 1. 引入一个模块 QT       += core gui sql
// 2. 引入头文件
// 3. 使用QSqlDatabase 来进行操作// 根据用户名和密码来判断,用户是否存在数据库中
bool Sqlite3Db::isContain(QString userName, QString passWord, OperatorInfo &infos) {QSqlDatabase db;db.setHostName("localhost");//设置主机名db = QSqlDatabase::addDatabase("QSQLITE");//添加数据库类型db.setDatabaseName("warehouse.db");  // 设置数据库名称bool isOpen = db.open();//打开连接//输出错误信息// qDebug() << isOpen ;// qDebug() << db.isValid();  // true// qDebug() << db.isOpen();   // true// 1.准备查询QSqlQuery 对象QSqlQuery query(db);// 2. 准备Sql语句? :占位符---避免sql注入QString sqlCmd = QString("SELECT * from operatorInfo where username=? and password=?");// 3.准备参数化占位符的数据query.prepare(sqlCmd);query.bindValue(0, userName);query.bindValue(1, passWord);//4.开始执行语句bool success = query.exec();if (success == false) {db.close();  // 网络资源,需要回收return false;}if (query.next() == false) {db.close();  // 网络资源,需要回收return false;}// 如果继续往后执行,就是已经买查询到对象了,返回这个对象的每个属性值OperatorInfo i;i.id = query.value(0).toInt();i.icon = query.value(1).toByteArray();i.username = query.value(2).toString();i.password = query.value(3).toString();i.addr = query.value(4).toString();i.gender = query.value(5).toInt();i.name = query.value(6).toString();i.phoneNo = query.value(7).toString();infos = i;db.close();return true;
}// //查询列表
// bool Sqlite3Db::selectOperators(OperatorInfoList &operatorinfs)
// {
//     QSqlDatabase db;
//     db.setHostName("localhost");//设置主机名
//     db = QSqlDatabase::addDatabase("QSQLITE");//添加数据库类型
//     db.setDatabaseName("warehouse.db");  // 设置数据库名称
//     bool isOpen = db.open();//打开连接
//     //输出错误信息
//     qDebug() << isOpen ;
//     qDebug() << db.isValid();  // true
//     qDebug() << db.isOpen();   // true//     // 1.准备查询QSqlQuery 对象
//     QSqlQuery query(db);
//     // 2. 准备Sql语句? :占位符---避免sql注入
//     QString sqlCmd = QString("SELECT * from operatorInfo ");
//     // 3.准备 数据
//     //query.prepare(sqlCmd);//     //4.开始执行语句
//     bool success = query.exec(sqlCmd);
//     if (success == false) {
//         db.close();  // 网络资源,需要回收
//         OperatorInfoList list;
//         operatorinfs=list;
//         return false;
//     }//     // 循环属性值
//     while(query.next()){
//         OperatorInfo i;
//         i.id = query.value(0).toInt();
//         i.icon = query.value(1).toByteArray();
//         i.username = query.value(2).toString();
//         i.password = query.value(3).toString();
//         i.addr = query.value(4).toString();
//         i.gender = query.value(5).toInt();
//         i.name = query.value(6).toString();
//         i.phoneNo = query.value(7).toString();
//         operatorinfs.push_back(i);
//     }
//     db.close(); // 网络资源,需要回收
//     return true;
// }//查询列表,支持分页
bool Sqlite3Db::selectOperators(QString searchString,int pageIndex,int pageSize,int &pageCount, OperatorInfoList &operatorinfs)
{QSqlDatabase db;db.setHostName("localhost");//设置主机名db = QSqlDatabase::addDatabase("QSQLITE");//添加数据库类型db.setDatabaseName("warehouse.db");  // 设置数据库名称bool isOpen = db.open();//打开连接//输出错误信息qDebug() << isOpen ;qDebug() << db.isValid();  // trueqDebug() << db.isOpen();   // true// 1.准备查询QSqlQuery 对象QSqlQuery query(db);// 2. 准备Sql语句? :占位符---避免sql注入QString strWhere=QString(" and 1=1");if(searchString.isNull()==false && searchString.isEmpty()==false){strWhere=QString("  and (name like '%%1%' or username like '%%2%')").arg(searchString).arg(searchString);}//查询分页数据QString datasql = QString("SELECT * from operatorInfo where 1=1 %1 limit %2 offset %3 ").arg(strWhere).arg(pageSize).arg((pageIndex - 1) * pageSize);//查询总页数QString pageCoutSql = QString("select count(id) from operatorInfo where 1=1 %1 ").arg(strWhere);//4.开始执行语句bool success = query.exec(datasql);if (success == false) {db.close();  // 网络资源,需要回收OperatorInfoList list;operatorinfs=list;return false;}// 循环属性值while(query.next()){OperatorInfo i;i.id = query.value(0).toInt();i.icon = query.value(1).toByteArray();i.username = query.value(2).toString();i.password = query.value(3).toString();i.addr = query.value(4).toString();i.gender = query.value(5).toInt();i.name = query.value(6).toString();i.phoneNo = query.value(7).toString();operatorinfs.push_back(i);//将数据添加到列表中}// 开始查询总条数,计算总页数bool success2 = query.exec(pageCoutSql);if (success2) {if (query.next()) {int dataCount = query.value(0).toInt();pageCount = dataCount / pageSize;if (dataCount % pageSize > 0) {pageCount = pageCount + 1;}}}db.close(); // 网络资源,需要回收return true;
}//添加数据
bool Sqlite3Db::insertOperator(const OperatorInfo &opt)
{QSqlDatabase db;db.setHostName("localhost");//设置主机名db = QSqlDatabase::addDatabase("QSQLITE");//添加数据库类型db.setDatabaseName("warehouse.db");  // 设置数据库名称bool isOpen = db.open();//打开连接qDebug() << db.isOpen();   // true// 1.准备查询QSqlQuery 对象QSqlQuery query(db);// 2. 准备Sql语句query.prepare("insert into operatorInfo(icon,username,password,addr,gender,name,phoneNo) values (?,?,?,?,?,?,?);");query.bindValue(0, opt.icon);query.bindValue(1, opt.username);query.bindValue(2, opt.password);query.bindValue(3, opt.addr);query.bindValue(4, opt.gender);query.bindValue(5, opt.name);query.bindValue(6, opt.phoneNo);//3.开始执行语句bool success = query.exec();db.close(); // 网络资源,需要回收return success;
}//删除数据
bool Sqlite3Db::deleteOperator(qint64 id)
{QSqlDatabase db;db.setHostName("localhost");//设置主机名db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName("warehouse.db");  // 设置数据库名称db.open();QSqlQuery query(db);query.prepare("delete from operatorInfo where id=?");query.bindValue(0, id);bool success = query.exec();db.close();return success;
}//根据id查询一条数据
bool Sqlite3Db::selectOperatorsById(qint64 id, OperatorInfo &operatorinfo)
{QSqlDatabase db;db.setHostName("localhost");//设置主机名db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName("warehouse.db");  // 配置数据库的地址db.open();QSqlQuery query(db);query.prepare("SELECT * from operatorInfo where id=?");query.bindValue(0, id);bool success = query.exec();if (success & query.next()) {operatorinfo.id = query.value(0).toInt();operatorinfo.icon = query.value(1).toByteArray();operatorinfo.username = query.value(2).toString();operatorinfo.password = query.value(3).toString();operatorinfo.addr = query.value(4).toString();operatorinfo.gender = query.value(5).toInt();operatorinfo.name = query.value(6).toString();operatorinfo.phoneNo = query.value(7).toString();db.close();  // 网络资源,需要回收return true;}return false;
}// 更新数据
bool Sqlite3Db::updateOperator(OperatorInfo info) {QSqlDatabase db;if (QSqlDatabase::contains("qt_sql_default_connection")) {db = QSqlDatabase::database("qt_sql_default_connection");} else{db = QSqlDatabase::addDatabase("QSQLITE");}db.setHostName("localhost");//设置主机名db.setDatabaseName("warehouse.db");  // 设置数据库名db.open();                           // 打开连接QString sqlCmd = QString("update operatorInfo set icon = ?,username = ?,addr = ?,gender = ?,name = ?,phoneNo = ? where id = ?");QSqlQuery query(db);query.prepare(sqlCmd);query.bindValue(0, info.icon);query.bindValue(1, info.username);query.bindValue(2, info.addr);query.bindValue(3, info.gender);query.bindValue(4, info.name);query.bindValue(5, info.phoneNo);query.bindValue(6, info.id);bool success = query.exec();if (!success) {qDebug() << "Error executing SQL statement:" << query.lastError().text();}db.close();return success;
}

6、测试效果

7、小结

信号和槽绑定的注意事项

使用QObject::connect函数进行绑定,这是最常用的绑定方式,通过指定发送者、信号、接收者和槽函数四个参数完成绑定。如果信号和槽的参数类型匹配,QT会自动进行类型转换

线程安全 信号和槽的跨线程连接默认使用队列方式,确保线程安全。如果发送者和接收者在同一线程,则使用直接方式。

信号和槽的参数匹配 信号和槽的参数数量和类型应该匹配,信号的参数可以比槽多,多余的参数会被忽略。QT支持基本类型的自动转换。

连接成功的判断 connect函数会返回一个QMetaObject::Connection对象,可以用来判断连接是否成功,或者后续断开连接。

原创不易,打字不易,截图不易,撸码不易,整理不易,走过路过,不要错过,欢迎点赞,收藏,转载,复制,抄袭,留言,灌水,请动动你的金手指,祝您早日实现财务自由。

http://www.dtcms.com/a/438026.html

相关文章:

  • Redis Zset的底层秘密:跳表(Skip List)的精妙设计
  • 广州金融网站建设2017网站开发语言排名
  • C++ priority_queue优先级队列
  • Kafka 授权与 ACL 深入实践
  • 西宁市住房和城乡建设局网站做一个个人网站
  • 瑞安做网站多少钱东莞网站建设找谁
  • 谷歌云+Apache Airflow,数据处理自动化的强力武器
  • 小红书自动化运营:智能体+RPA自动化+MCP实现采集仿写和自动发布
  • 网站域名和网站网址建筑培训网 江苏
  • 定制开发开源AI智能名片S2B2C商城小程序的会员制运营研究——以“老铁用户”培养为核心目标
  • 【aigc】chrome-devtools-mcp怎么玩?
  • 从《Life of A Pixel》来看Chrome的渲染机制
  • 【项目实战 Day9】springboot + vue 苍穹外卖系统(用户端订单模块 + 商家端订单管理模块 完结)
  • Mac 安装Neo4j教程
  • blender 解决shift快捷键和中英切换重复的问题
  • 网站动态图怎么做阳明拍卖公司网站
  • 01_Docker 部署 Ollama 模型(支持 NVIDIA GPU)
  • 苏州新区网站制作wordpress视频格式
  • 一位Android用户的科技漫游手记
  • android中调用相册
  • 安卓基础组件031-Retrofit 网络请求框架
  • Redis 黑马点评-商户查询缓存
  • Android geckoview 集成,JS交互,官方demo
  • 【APK安全】Android 权限校验核心风险与防御指南
  • 单调队列与单调栈
  • 设计与优化Java API:构建高效、可维护的接口
  • Locality Sensitive Hashing (LSH) 详解:高效检测语言语句重复的利器
  • 阿里云网站开发零起步如何做设计师
  • 后端开发基础概念MVC以及Entity,DAO,DO,DTO,VO等概念
  • 七大排序算法的基本原理