2.关于QT中数据库操作,简单数据库连接操作,数据库的增删改查,QSqlTableModel和QTableView,事务操作,关于QItemDelegate 代理
来源:互联网 发布:mac怎么玩免费的游戏 编辑:程序博客网 时间:2024/05/19 21:44
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+=guiwidgets 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+=guiwidgets 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();
}
运行结果:
Widget05.h
#ifndefWIDGET05_H
#defineWIDGET05_H
#include<QWidget>
#include<QSqlQueryModel>
#include<QTableView>
classWidget05:publicQWidget
{
Q_OBJECT
public:
explicitWidget05(QWidget*parent= 0);
QSqlQueryModel*_model;
QTableView*_view;
signals:
publicslots:
};
#endif//WIDGET05_H
Widget05.cpp
#include"Widget05.h"
#include<QSqlQuery>
#include<QVBoxLayout>
Widget05::Widget05(QWidget*parent):
QWidget(parent)
{
_model=newQSqlQueryModel;
_view=newQTableView(this);
_view->setModel(_model);
_model->setQuery("select*fromtuser");
_model->query();
QVBoxLayout*lay=newQVBoxLayout(this);
lay->addWidget(_view);
}
main.cpp
#include <QApplication>
#include "Widget05.h"
#include <QSqlDatabase>
#include <QSqlError>
#include <QDebug>
#include "Contact.h"
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要写在上面代码的下面
Widget05 w;
w.show();
return app.exec();
}
运行结果:
- 2.关于QT中数据库操作,简单数据库连接操作,数据库的增删改查,QSqlTableModel和QTableView,事务操作,关于QItemDelegate 代理
- 关于操作数据库增删改查
- 数据库的简单操作----增删改查
- 关于JDBC 对数据库进行创建以及简单的增删改查操作
- 关于MySql中数据库、表的操作以及增删改查等一些SQL语句注意事项
- 数据库---简单的使用Java操作数据库增删改查
- 关于ADO.NET数据库操作中的增删改查讲解
- 数据库操作增删改查
- 数据库操作--增删改查
- Oracle数据库的增删改查(简单操作)
- loner_li Oracle数据库的增删改查(简单操作)
- MyBatis对数据库的增删改查操作,简单示例
- MyBatis对数据库的增删改查操作,简单示例
- mysql数据库简单的增删改查,数据导出操作
- 数据库的增删改查操作
- 数据库的一些增删改查操作
- 关于hbase增删改查的操作
- Java数据库连接--JDBC基础知识(操作数据库:增删改查)
- 二分法求多项式根
- 为什么你的工作这么低效
- Leetcode Missing Ranges
- LeetCode: Jump Game
- LeetCode刷题笔录Interleaving String
- 2.关于QT中数据库操作,简单数据库连接操作,数据库的增删改查,QSqlTableModel和QTableView,事务操作,关于QItemDelegate 代理
- [BZOJ 2799]POI 2012 Salaries
- Leetcode One Edit Distance
- Leetcode Intersection of Two Linked Lists
- 近期总结
- {12月13日}“大数据讲座听后感”
- a5.java
- HDU2051(数制转换)
- 复数