bool MainWindow::openDatabase(QString aFile)
DB=QSqlDatabase::addDatabase("QSQLITE"); //添加 SQLITE数据库驱动
DB.setDatabaseName(aFile); //设置数据库名称
if (!DB.open()) //打开数据库失败
return false;
openTable(); //打开数据表
return true;
3.QTableView和QSqltableModedl、QItemSelectionModel关系
/打开数据表
void MainWindow::openTable()
//1. 创建数据模型,打开数据表
tabModel=new QSqlTableModel(this,DB); //数据模型
tabModel->setTable("employee"); //设置数据表
tabModel->setEditStrategy(QSqlTableModel::OnManualSubmit); //数据保存方式,OnManualSubmit , OnRowChange
tabModel->setSort(tabModel->fieldIndex("empNo"),Qt::AscendingOrder); //排序
if (!(tabModel->select())) //查询数据失败
QMessageBox::critical(this, "错误信息",
"打开数据表错误,错误信息:\n"+tabModel->lastError().text());
return;
showRecordCount(); //显示记录条数
//2. 设置字段显示标题
tabModel->setHeaderData(tabModel->fieldIndex("empNo"), Qt::Horizontal, "工号");
tabModel->setHeaderData(tabModel->fieldIndex("Name"), Qt::Horizontal, "姓名");
tabModel->setHeaderData(tabModel->fieldIndex("Gender"), Qt::Horizontal, "性别");
tabModel->setHeaderData(tabModel->fieldIndex("Birthday"), Qt::Horizontal, "出生日期");
tabModel->setHeaderData(tabModel->fieldIndex("Province"), Qt::Horizontal, "省份");
tabModel->setHeaderData(tabModel->fieldIndex("Department"), Qt::Horizontal, "部门");
tabModel->setHeaderData(tabModel->fieldIndex("Salary"), Qt::Horizontal, "工资");
//这两个字段不在tableView中显示
tabModel->setHeaderData(tabModel->fieldIndex("Memo"),Qt::Horizontal,"备注");
tabModel->setHeaderData(tabModel->fieldIndex("Photo"),Qt::Horizontal,"照片");
//3. 创建选择模型
selModel=new QItemSelectionModel(tabModel,this); //关联选择模型
//当前行或列变化时发射currentChanged信号
connect(selModel,&QItemSelectionModel::currentChanged,
this,&MainWindow::do_currentChanged);
//当前行变化时发射currentRowChanged()信号
connect(selModel,&QItemSelectionModel::currentRowChanged,
this,&MainWindow::do_currentRowChanged);
//4. Model/View结构
ui->tableView->setModel(tabModel); //设置数据模型
ui->tableView->setSelectionModel(selModel); //设置选择模型
ui->tableView->setColumnHidden(tabModel->fieldIndex("Memo"),true); //隐藏列
ui->tableView->setColumnHidden(tabModel->fieldIndex("Photo"),true); //隐藏列
//5. 为tableView中的“性别”和“部门”两个字段设置自定义代理组件
QStringList strList;
strList<<"男"<<"女";
bool isEditable=false;
delegateSex.setItems(strList,isEditable);
ui->tableView->setItemDelegateForColumn(
tabModel->fieldIndex("Gender"),&delegateSex); //设置代理组件
strList.clear();
strList<<"销售部"<<"技术部"<<"生产部"<<"行政部";
isEditable=true;
delegateDepart.setItems(strList,isEditable);
ui->tableView->setItemDelegateForColumn(
tabModel->fieldIndex("Department"),&delegateDepart); //设置代理组件
//6. 创建界面组件与数据模型的字段之间的数据映射
dataMapper= new QDataWidgetMapper(this);
dataMapper->setModel(tabModel); //设置数据模型
dataMapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit); //数据更新方式
//界面组件与数据模型的具体字段之间的联系
dataMapper->addMapping(ui->dbSpinEmpNo,tabModel->fieldIndex("empNo"));
dataMapper->addMapping(ui->dbEditName,tabModel->fieldIndex("Name"));
dataMapper->addMapping(ui->dbComboSex,tabModel->fieldIndex("Gender"));
dataMapper->addMapping(ui->dbEditBirth,tabModel->fieldIndex("Birthday"));
dataMapper->addMapping(ui->dbComboProvince,tabModel->fieldIndex("Province"));
dataMapper->addMapping(ui->dbComboDep,tabModel->fieldIndex("Department"));
dataMapper->addMapping(ui->dbSpinSalary,tabModel->fieldIndex("Salary"));
dataMapper->addMapping(ui->dbEditMemo,tabModel->fieldIndex("Memo"));
dataMapper->toFirst(); //移动到首记录
//7. 获取字段名称列表,填充groupBoxSort
getFieldNames();
//8.更新actions和界面组件的使能状态
ui->actOpenDB->setEnabled(false); //不能再打开数据库
ui->actRecAppend->setEnabled(true);
ui->actRecInsert->setEnabled(true);
ui->actRecDelete->setEnabled(true);
ui->actScan->setEnabled(true);
ui->groupBoxSort->setEnabled(true); //"排序"分租框
ui->groupBoxFilter->setEnabled(true); //"数据过滤"分组框
4.设置设置自定义代理组件
//5. 为tableView中的“性别”和“部门”两个字段设置自定义代理组件
QStringList strList;
strList<<"男"<<"女";
bool isEditable=false;
delegateSex.setItems(strList,isEditable);
ui->tableView->setItemDelegateForColumn(
tabModel->fieldIndex("Gender"),&delegateSex); //设置代理组件
strList.clear();
strList<<"销售部"<<"技术部"<<"生产部"<<"行政部";
isEditable=true;
delegateDepart.setItems(strList,isEditable);
ui->tableView->setItemDelegateForColumn(
tabModel->fieldIndex("Department"),&delegateDepart); //设置代理组件
这是我工作了一天的成果,压缩包内包括Qt sqlite加密驱动所有的代码,以及一个调用例程,还有一个sqlite3shell.exe工具,用于加密数据库命令行下的分析。
使用这个加密驱动很简单,只需以下3步:
1. 将驱动的代码复制到你的app文件夹(共2个文件夹)
2. 在app的pro文件中加入
include(wxsqlite3/wxsqlite3.pri)
include(zsqlitecipherdriver/zsqlitecipherdriver.pri)
3. 在需要的地方加入#include "zsqlitecipherdriver.h",这样就可以使用ZSQLiteCipherDriver类了,这个类是继承自QSqlDriver。所以可以传递给
QSqlDatabase::addDatabase。
详细的可以查看压缩包内源码。之后,main函数就可以这么使用sqlite的加密驱动:
ZSQLiteCipherDriver *driver = new ZSQLiteCipherDriver();
QSqlDatabase db = QSqlDatabase::addDatabase(driver);
db.setDatabaseName("test.db");
db.setPassword("123");
db.open();
加密驱动的稳定性没有问题,是我从Qt的开源代码中,找到Sqlite没加密的驱动部分,然后修改的。修改的内容不多,最重要的是在数据库的open时,加入了sqlite3_key的调用,实现加密。
底层的加密实现,是来自wxsqlite3-3.0.6。这个我修改了一个宏定义,让其加密方式采用了AES256,而不是原来的AES128。
例程中包括了3个实用的函数,分别用来以某一密码打开或创建一个数据库,判断数据库是否处于解密状态,以及修改数据库密码。
sqlite3shell.exe跟官方提供的sqlite3.exe使用方法一样。只不过对于加密数据库,需要在对数据库进行任何操作前,先执行“PRAGMA key=xxx;”。通过这种方式输入数据库密码。检验之前的密码是否正确可以在命令行中键入“.databases”,如果没有错误提示,那就是解密成功了;如果密码错误,只能关闭sqlite3shell.exe,从头尝试了。
虽然这个资源,要的分数确实有点多,不过评价之后就能返还的。我相信这个资源值这个价值!下载后在Qt5上可以直接编译。不需要任何修改。Qt4上没试过,不承诺一定可用,但是应该没问题。
qt的sqlite加密插件,资源在qt5.9.5下编译。可以直接放到qt插件目录下使用。将产生的sqlitecipher.dll拷贝到plugins\sqldrivers路径下。打开方式如下:
QSqlDatabase dbconn = QSqlDatabase::addDatabase("SQLITECIPHER");
dbconn.setDatabaseName("test.db");
dbconn.setPassword("test");
//dbconn.setConnectOptions("QSQLITE_CREATE_KEY") 创建密码
//dbconn.setConnectOptions("QSQLITE_REMOVE_KEY") 清空密码
if (!dbconn.open())
qDebug() << "Can not open connection: " << dbconn.lastError().driverText();
QSqlDatabase database;
database = QSqlDatabase::addDatabase("QSQLITE");
// qDebug() << QApplication::applicationDirPath(); // 获取应用程序当前目录
database.setDatabaseName("test.sqlite3");
本文代码在博文:https://blog.csdn.net/frieryumao/article/details/93871774 基础上实现创建数据库并实现数据库访问。
#ifndef DATABASESQL_H
#define DATABASESQL_H
/*******************************************************************...