2.关于QT中数据库操作,简单数据库连接操作,数据库的增删改查,QSqlTableModel和QTableView,事务操作,关于QItemDelegate 代理
Linux下的qt安装,命令时:sudoapt-get install qt-sdk
安装mysql数据库,安装方法参考博客:http://blog.csdn.net/tototuzuoquan/article/details/39565783
如果行想进数据库开发,需要安装libqt5sql5-mysql.命令是:
sudo apt-get install libqt5sql5-mysql
4 创建一个项目
要调用数据库,需要加上QT += gui widgets sql 也就是说要加上sql库
注意如果是在windows平台下:要将C:/MySQL/bin目录下的libmySQL.dll拷贝到项目编译后的生成的exe文件所在的同级目录下(比如目录E:\QT\build-Database01-Desktop_Qt_5_3_MinGW_32bit-Debug\debug下,在此目录下有Database01.exe)。比如截图:
A 如果是在Linux目录下,输入以下命令:mysql-u root -p123456
创建数据库:
B使用数据库d0718,并创建所需的数据库表
表内容如下:
CREATE TABLE `tcontact` ( `username` varchar(32) NOT NULL, `mobile` varchar(16) NOT NULL, `mobile2` varchar(16) NOT NULL, `telephone` varchar(32) DEFAULT NULL, `home` varchar(32) DEFAULT NULL, `homeaddr` varchar(1024) DEFAULT NULL, `company` varchar(128) DEFAULT NULL, `companyaddr` varchar(1024) DEFAULT NULL, `title` varchar(16) DEFAULT NULL, PRIMARY KEY (`mobile`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
CREATE TABLE `tuser` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'this is userid', `username` varchar(32) NOT NULL COMMENT 'username', `password` varchar(32) NOT NULL COMMENT 'password', `gender` int(11) NOT NULL COMMENT '1 is male 0 is female', PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
C 编写项目代码:
Database01.pro |
SOURCES+=\ main.cpp QT+=gui widgets sql CONFIG+=C++11 |
main.cpp |
#include <QApplication> #include <QSqlDatabase> #include <QSqlError> #include <QDebug> #include <QWidget> int main(int argc,char* argv[]) { QApplication app(argc,argv); QWidget w; /*QT可以操作 QSLITE QODBC,QPLSQL 这些数据库*/ //下面表示使用mysql数据库 QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); db.setHostName("127.0.0.1"); //设置数据库所在位置 db.setUserName("root"); //设置数据库的用户名 db.setPassword("123456"); //设置数据库的密码 db.setDatabaseName("d0718"); //设置数据库名称 bool bRet = db.open(); //打开数据库连接 if(bRet == false) { //说明可以通过db.lastError()的方式得到错误信息 qDebug() << "error open database" << db.lastError().text(); exit(0); } qDebug() << "open database success"; w.show(); return app.exec(); } |
运行结果: |
案例二: |
Database01.pro的内容如下: |
SOURCES += \ main.cpp \ Widget01.cpp QT += gui widgets sql #如果用到C++11的才会用到,否则不用 CONFIG += C++11 HEADERS += \ Widget01.h |
Widget01.h的内容如下: |
#ifndef WIDGET01_H #define WIDGET01_H #include <QWidget> class Widget01 : public QWidget { Q_OBJECT public: explicit Widget01(QWidget *parent = 0); signals: public slots: }; #endif // WIDGET01_H |
Widget01.cpp的内容如下: |
#include "Widget01.h" #include <QSqlDatabase> #include <QSqlError> #include <QSqlQuery> #include <QSqlResult> #include <QDebug> Widget01::Widget01(QWidget *parent) : QWidget(parent) { QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); db.setHostName("127.0.0.1"); db.setUserName("root"); db.setPassword("123456"); db.setDatabaseName("d0718"); bool bRet = db.open(); if(bRet == false) { qDebug() << "error open database" << db.lastError().text(); exit(0); } qDebug() << "open database success"; //向数据库中添加数据 db.exec("insert into tuser(username,password,gender) values('涂作权','123456','1')"); db.close(); } |
main.cpp的内容如下: |
#include <QApplication> #include "Widget01.h" int main(int argc,char* argv[]) { QApplication app(argc,argv); Widget01 w; w.show(); return app.exec(); } |
运行结果: |
案例2,使用QSqlTableModel |
Database01.pro |
SOURCES += \ main.cpp \ Widget02.cpp QT += gui widgets sql CONFIG += C++11 HEADERS += \ Widget02.h |
Widget02.h |
#ifndef WIDGET02_H #define WIDGET02_H #include <QWidget> class Widget02 : public QWidget { Q_OBJECT public: explicit Widget02(QWidget *parent = 0); signals: public slots: }; #endif // WIDGET02_H |
Widget02.cpp |
#include "Widget02.h" #include <QSqlDatabase> #include <QSqlTableModel> #include <QSqlRecord> #include <QDebug> #include <QSqlError> Widget02::Widget02(QWidget *parent) : QWidget(parent) { // QSqlTableModel: 数据表对应的数据结构 QSqlTableModel model; //设置表名,通过这种方式不用写sql语句了 model.setTable("tuser"); //设置过滤器,当加上这一句的时候只返回用户名不是"toto"数据 //model.setFilter("username<>'toto'"); model.select(); // exec query int ret = model.rowCount(); // read data from database for(int i=0; i<ret; ++i) { QSqlRecord record = model.record(i); for(int j=0; j<record.count(); j++) { qDebug() << record.value(j); } } // update data to database //将第0行(脚标以0开始),第1列的数据改成toto //注意只能修改上满select出来的结果。 model.setData(model.index(2, 1), "tototuzuoquan"); //要想让上面的这一句也执行成功,要放开下面一句 model.submitAll(); // insert data to database QSqlRecord record = model.record(); //可以指定id的值,通过下面的方式实现向数据库中插入一条记录 // record.setValue("id", ); record.setValue("username", "toto12"); record.setValue("password", "password12"); record.setValue("gender", 1); model.insertRecord(-1, record); model.submitAll(); } |
main.cpp |
#include <QApplication> #include "Widget02.h" #include <QSqlDatabase> #include <QSqlError> #include <QDebug> int main(int argc,char* argv[]) { QApplication app(argc,argv); /*QT可以操作 QSLITE QODBC,QPLSQL 这些数据库*/ //下面表示使用mysql数据库,因为这里的db没有用到db,所以可以把它放在main中 //本质:在QT里面打开一个数据库之后,就会保存一个数据库连接, //其它的位置就可以任意使用这个全局的变量了 QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); db.setHostName("127.0.0.1"); //设置数据库所在位置 db.setUserName("root"); //设置数据库的用户名 db.setPassword("123456"); //设置数据库的密码 db.setDatabaseName("d0718"); //设置数据库名称 bool bRet = db.open(); //打开数据库连接 if(bRet == false) { //说明可以通过db.lastError()的方式得到错误信息 qDebug() << "error open database" << db.lastError().text(); exit(0); } qDebug() << "open database success"; //注意Widget02要写在上面代码的下面 Widget02 w; w.show(); return app.exec(); } |
运行结果: 数据库中的变化的内容如下: |
案例三(QTableView),事务操作: |
Database01.pro |
SOURCES += \ main.cpp \ Widget03.cpp QT += gui widgets sql CONFIG += C++11 HEADERS += \ Widget03.h |
Widget03.h |
#ifndef WIDGET03_H #define WIDGET03_H #include <QObject> #include <QSqlTableModel> #include <QTableView> // show table class Widget03 : public QWidget { Q_OBJECT public: explicit Widget03(QWidget *parent = 0); QSqlTableModel* _model; QTableView* _view; signals: public slots: void slotSubmitClicked(); void slotDelClicked(); void slotAddClicked(); }; #endif // WIDGET03_H |
Widget03.cpp |
#include "Widget03.h" #include <QVBoxLayout> #include <QHBoxLayout> #include <QPushButton> #include <QMessageBox> #include <QSqlError> #include <QSqlDatabase> #include <QSqlRecord> Widget03::Widget03(QWidget *parent) : QWidget(parent) { _model = new QSqlTableModel; _model->setTable("tuser"); _model->select(); _model->setEditStrategy(QSqlTableModel::OnManualSubmit); _model->setHeaderData(0, Qt::Horizontal, "编号"); _model->setHeaderData(1, Qt::Horizontal, "用户名"); _model->setHeaderData(2, Qt::Horizontal, "密码"); _model->setHeaderData(3, Qt::Horizontal, "性别"); _view = new QTableView; //_view中添加_model _view->setModel(_model); //隐藏第3列 //_view->hideColumn(2); QVBoxLayout* lay = new QVBoxLayout(this); lay->addWidget(_view); QHBoxLayout* hBox = new QHBoxLayout; lay->addLayout(hBox); hBox->addStretch(); //删除的信号和槽 QPushButton* del = new QPushButton("del"); connect(del, SIGNAL(clicked()), this, SLOT(slotDelClicked())); hBox->addWidget(del); //提交的信号和槽 QPushButton* submit = new QPushButton("submit"); connect(submit, SIGNAL(clicked()), this, SLOT(slotSubmitClicked())); hBox->addWidget(submit); //添加的信号和槽 QPushButton* add = new QPushButton("add"); connect(add, SIGNAL(clicked()), this, SLOT(slotAddClicked())); hBox->addWidget(add); } /** * @brief Widget03::slotAddClicked 添加的槽 */ void Widget03::slotAddClicked() { //开启事务 _model->database().transaction(); QSqlRecord record = _model->record(); _model->insertRecord(-1,record); } /** * @brief Widget03::slotDelClicked 删除的信号槽 */ void Widget03::slotDelClicked() { // 通过_view去获取被选中的部分的数据model QItemSelectionModel * selectModel = _view->selectionModel(); // 通过选中的数据结构,获取这些格子的ModelIndex QModelIndexList selectList = selectModel->selectedIndexes(); QList<int> delRow; // 遍历这些格子,获取格子所在行,因为可能存在相同的行,所以要去重 for(int i=0; i<selectList.size(); ++i) { QModelIndex index = selectList.at(i); // _model->removeRow(index.row()); delRow << index.row(); } while(delRow.size() > 0) { int row = delRow.at(0); delRow.removeAll(row); _model->removeRow(row); } _model->submitAll(); } void Widget03::slotSubmitClicked() { if(!_model->submitAll()) { QMessageBox::critical(this, "Error", QSqlDatabase().lastError().text()); _model->database().rollback(); } else { _model->database().commit(); } } |
main.cpp |
#include <QApplication> #include "Widget03.h" #include <QSqlDatabase> #include <QSqlError> #include <QDebug> int main(int argc,char* argv[]) { QApplication app(argc,argv); /*QT可以操作 QSLITE QODBC,QPLSQL 这些数据库*/ //下面表示使用mysql数据库,因为这里的db没有用到db,所以可以把它放在main中 //本质:在QT里面打开一个数据库之后,就会保存一个数据库连接, //其它的位置就可以任意使用这个全局的变量了 QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); db.setHostName("127.0.0.1"); //设置数据库所在位置 db.setUserName("root"); //设置数据库的用户名 db.setPassword("123456"); //设置数据库的密码 db.setDatabaseName("d0718"); //设置数据库名称 bool bRet = db.open(); //打开数据库连接 if(bRet == false) { //说明可以通过db.lastError()的方式得到错误信息 qDebug() << "error open database" << db.lastError().text(); exit(0); } qDebug() << "open database success"; //注意Widget02要写在上面代码的下面 Widget03 w; w.show(); return app.exec(); } |
运行结果: |
案例四:关于QItemDelegate代理 |
Database01.pro |
SOURCES+=\ main.cpp\ Widget04.cpp QT+=gui widgets sql CONFIG+=C++11 HEADERS+=\ Widget04.h |
Widget04.h |
#ifndefWIDGET04_H #defineWIDGET04_H #include<QObject> #include<QSqlTableModel> #include<QTableView>//showtable #include<QItemDelegate> #include<QComboBox> /** *@briefTheTUserDelegateclass对整张表进行代理 */ classTUserDelegate:publicQItemDelegate { QWidget*createEditor(QWidget*parent, constQStyleOptionViewItem&option, constQModelIndex&index)const { if(index.column()==0) returnNULL; if(index.column()==3) { QComboBox* combo=newQComboBox(parent); combo->addItem("男"); combo->addItem("女"); returncombo; } returnQItemDelegate::createEditor(parent,option,index); } }; /** *@briefTheReadOnlyDelegateclass做一个只读的代理 */ classReadOnlyDelegate:publicQItemDelegate { QWidget*createEditor(QWidget*, constQStyleOptionViewItem&, constQModelIndex&)const { returnNULL; } }; /** *@briefTheGenderDelegateclass对指定列进行代理 */ classGenderDelegate:publicQItemDelegate { public: QWidget*createEditor(QWidget*parent, constQStyleOptionViewItem&, constQModelIndex&)const { QComboBox* combo=newQComboBox(parent); combo->addItem("男"); combo->addItem("女"); returncombo; } }; /** *@briefTheMyTableModelclass对TableModel的重写 */ classMyTableModel:publicQSqlTableModel { public: QVariantdata(constQModelIndex&idx,introle=Qt::DisplayRole)const { // if(role==Qt::DisplayRole) // returnQSqlTableModel::data(idx,role); //如果不是第三列,直接返回 if(idx.column()!=3) returnQSqlTableModel::data(idx,role); //如果是第三列 QVariantvar=QSqlTableModel::data(idx,role); if(var==0) { return"女"; } return"男"; } boolsetData(constQModelIndex&index,constQVariant&value,introle=Qt::EditRole) { if(index.column()!=3) returnQSqlTableModel::setData(index,value,role); if(value=="男") returnQSqlTableModel::setData(index,1,role); returnQSqlTableModel::setData(index,0,role); } }; classWidget04:publicQWidget { Q_OBJECT public: explicitWidget04(QWidget*parent= 0); MyTableModel*_model; QTableView*_view; signals: publicslots: voidslotSubmitClicked(); voidslotDelClicked(); voidslotAddClicked(); }; #endif//WIDGET04_H |
Widget04.cpp |
#include"Widget04.h" #include<QVBoxLayout> #include<QHBoxLayout> #include<QPushButton> #include<QMessageBox> #include<QSqlError> #include<QSqlDatabase> #include<QSqlRecord> Widget04::Widget04(QWidget*parent): QWidget(parent) { _model=newMyTableModel; _model->setTable("tuser"); _model->select(); //数据库的提交策略是手动提交 _model->setEditStrategy(QSqlTableModel::OnManualSubmit); //改变现实的表的名字 _model->setHeaderData(0,Qt::Horizontal,"编号"); _model->setHeaderData(1,Qt::Horizontal,"用户名"); _model->setHeaderData(2,Qt::Horizontal,"密码"); _model->setHeaderData(3,Qt::Horizontal,"性别"); _view=newQTableView; _view->setModel(_model); // _view->hideColumn(2); //下面是为指定的列设置代理 // _view->setItemDelegateForColumn(3,newGenderDelegate); //_view->setItemDelegateForColumn(0,newReadOnlyDelegate); //为整个表设置代理 _view->setItemDelegate(newTUserDelegate); QVBoxLayout*lay=newQVBoxLayout(this); lay->addWidget(_view); QHBoxLayout*hBox=newQHBoxLayout; lay->addLayout(hBox); hBox->addStretch(); //删除按钮 QPushButton*del=newQPushButton("del"); connect(del,SIGNAL(clicked()),this,SLOT(slotDelClicked())); hBox->addWidget(del); //提交按钮 QPushButton*submit=newQPushButton("submit"); connect(submit,SIGNAL(clicked()),this,SLOT(slotSubmitClicked())); hBox->addWidget(submit); //添加按钮 QPushButton*add=newQPushButton("add"); connect(add,SIGNAL(clicked()),this,SLOT(slotAddClicked())); hBox->addWidget(add); } voidWidget04::slotAddClicked() { QSqlRecordrecord=_model->record(); _model->insertRecord(-1,record); } voidWidget04::slotDelClicked() { //通过_view去获取被选中的部分的数据model QItemSelectionModel*selectModel=_view->selectionModel(); //通过选中的数据结构,获取这些格子的ModelIndex QModelIndexListselectList= selectModel->selectedIndexes(); QList<int>delRow; //遍历这些格子,获取格子所在行,因为可能存在相同的行,所以要去重 for(inti=0;i<selectList.size();++i) { QModelIndexindex=selectList.at(i); // _model->removeRow(index.row()); delRow<<index.row(); } while(delRow.size()>0) { introw=delRow.at(0); delRow.removeAll(row); _model->removeRow(row); } _model->submitAll(); } /** *@briefWidget04::slotSubmitClicked提交按钮 */ voidWidget04::slotSubmitClicked() { if(!_model->submitAll()) { QMessageBox::critical(this,"Error",QSqlDatabase().lastError().text()); } } |
main.cpp |
#include<QApplication> #include"Widget04.h" #include<QSqlDatabase> #include<QSqlError> #include<QDebug> intmain(intargc,char*argv[]) { QApplicationapp(argc,argv); /*QT可以操作QSLITEQODBC,QPLSQL这些数据库*/ //下面表示使用mysql数据库,因为这里的db没有用到db,所以可以把它放在main中 //本质:在QT里面打开一个数据库之后,就会保存一个数据库连接, //其它的位置就可以任意使用这个全局的变量了 QSqlDatabasedb=QSqlDatabase::addDatabase("QMYSQL"); db.setHostName("127.0.0.1"); //设置数据库所在位置 db.setUserName("root"); //设置数据库的用户名 db.setPassword("123456"); //设置数据库的密码 db.setDatabaseName("d0718"); //设置数据库名称 boolbRet=db.open(); //打开数据库连接 if(bRet==false) { //说明可以通过db.lastError()的方式得到错误信息 qDebug()<<"erroropendatabase"<<db.lastError().text(); exit(0); } qDebug()<<"opendatabasesuccess"; //注意Widget02要写在上面代码的下面 Widget04w; w.show(); returnapp.exec(); } |
运行结果: |
|
2.关于QT中数据库操作,简单数据库连接操作,数据库的增删改查,QSqlTableModel和QTableView,事务操作,关于QItemDelegate 代理相关推荐
- R操作MySQL数据库创建表、删除表、增删改查(CRUD)
R操作MySQL数据库创建表.删除表.增删改查(CRUD) 关系数据中的数据是按照一定范式去存储的.当我们需要非常高级和复杂的Sql查询就可以使用关系数据库的数据资产.不光java和python可以容 ...
- javaweb简单的登录增删改查系统_利用python操作小程序云数据库实现简单的增删改查!
不止python,你可以利用任何语言那实现通过http请求来操作你自己的小程序云数据库了 背景 也是在最近吧,小程序更新了云开发 HTTP API 文档,提供了小程序外访问云开发资源的能力,使用 HT ...
- resultset mysql_MySQL数据库学习笔记(九)----JDBC的ResultSet接口(查询操作)、PreparedStatement接口重构增删改查(含SQL注入的解释)...
[声明] 欢迎转载,但请保留文章原始出处→_→ [正文] 一.ResultSet接口的介绍: 对数据库的查询操作,一般需要返回查询结果,在程序中,JDBC为我们提供了ResultSet接口来专门处理查 ...
- MySQL数据库学习笔记(九)----JDBC的ResultSet接口(查询操作)、PreparedStatement接口重构增删改查(含SQL注入的解释)...
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- 使用三层架构实现简单的MVC登陆操作!并实现基本的增删改查功能!!
一丶使用三层架构创建一个简单的MVC登录操作 1.首先,创建一个项目以及BLL层.DAL层.Entity层,如图一: 图一 2.创建一个数据库如图二: 图二 3基本工作已做好,接下来就编BLL层.DA ...
- Web框架之Django_02基本操作(Django项目启动配置、数据库连接、orm、增删改查)
阅读目录 摘要: Django项目简单现实过程 pycharm连接数据库 Django之orm简单操作增删改查 一.新建Django项目.配置.设置: 新建Django项目:(为了熟悉Django操作 ...
- Java课设-简单的通讯录系统(增删改查连接数据库)
一.题目介绍 二.实验思路 这里主要是运用到了jdbc来连接数据库,而在数据库中存在的是通讯录的记录,有id,姓名,手机号,创建时间,修改时间.同时使用的是swing的来做可视化界面,其中运用到了弹窗 ...
- mysql存储过程 delete select insert_mysql常见操作语句,建表,增删改查
用户操作 新建用户 grant 权限 on 数据库.表名 to 用户名@'访问地址' identified by "密码"; 新建一个可以远程访问数据库的用户 test, 密码:p ...
- (写给像我一样刚离开校园进入公司的小菜鸟)在领域架构下,如何实现简单的展示页面以及增删改查(第二步)...
这一片就简单的介绍实现增删改查 首先是显示所有数据 Service=>>> 1 /// <summary> 2 /// 加载所有数据 3 /// </summary ...
- php 中curd表达啥,CURD语句的基本语法和PDO中操作数据表的基本步骤实例演示增删改查命令 2019年07月24日 23时10分...
一.常用的CUR 最常用的就是: `CURD` 增删改查 它代表创建(Create).更新(Update).读取(Read)和删除(Delete)操作. 新增操作语法 * SQL规范: `INSE ...
最新文章
- JMeter 聚合报告之 90% Line 参数说明
- 在eclipse中使用JDBC连接MySQL5.7.24
- LeetCode--023--合并K个排序链表
- python email模块
- exe4j生成可执行程序的使用方法
- PPT幻灯片从自动翻页设置为手动翻页技巧图文教程
- 旋流式沉砂池计算_以高效旋流器为核心的超低成本选煤技术
- jquery easyui 弹出消息框
- python离线安装包_Python2.7如何离线安装包
- vue 导出html
- SQL Server日期格式转换大全
- /etc/fstab详解
- 红帽企业版linux 7.3,红帽推企业Linux 7.3 新功能特性一览
- LabView中,下拉列表和枚举有什么区别?
- 【转】NodeJS教程--基于ExpressJS框架的文件上传
- 200 万年薪的博士,华为到底看重什么?
- vb html ie弹出窗口,VB6 统制IE弹出模式窗口
- Access denied for user 'root'@'localhost' Could not obtain connection
- u8 附件上传后存放路径_用友U8生产不良退料案例教程
- 如何把录音生成二维码,用微信扫一下就能听?分享语音音频转二维码的方法和技术原理
热门文章
- OpenCASCADE绘制测试线束:图形命令之Axonometric观察器
- wxWidgets:wxLogNull类用法
- wxWidgets:WxBase 事件循环
- wxWidgets:事件和事件处理
- boost::mpi模块实现scan集合的测试
- boost::iostreams::grep_filter用法的测试程序
- boost::hana::or_用法的测试程序
- boost::graph模块演示 GGCL Vertex 接口
- boost::describe模块实现连载功能的测试程序
- boost::hash_combine模块实现json哈希值的测试程序