QT数据库(二):QSqlQueryModel实现数据查询
QSqlQueryModel 可以设置任意的 SELECT 语句来从数据库中查询数据,可以查询一个数据表部分字段的数据,也可以是多个数据表组合的数据。该模型的数据是只读的,即使在界面上修改了QSqlQueryModel 模型的数据,也不能将所做的修改提交到数据库。
要从数据库查询数据并将其作为 QSqlQueryModel 的数据源,需要运行函数 setQuery()
有两种原型:
void QSqlQueryModel::setQuery(const QString &query, const QSqlDatabase &db = QSqlDatabase())
参数 query 是一条完整的 SELECT 查询语句;参数 db 是数据库连接,若不指定数据库连接, 就用程序默认的数据库连接。
void QSqlQueryModel::setQuery(QSqlQuery &&query)
QSqlQuery 是可以运行任何 SQL 语句的类,当然也能运行 SELECT 语句从数据库获取数据。
查询出数据后,可以用 QSqlQueryModel 的函数 record()访问数据记录。
//1. 创建数据模型,查询数据
qryModel=new QSqlQueryModel(this);
qryModel->setQuery("SELECT empNo, Name, Gender, Birthday, Province, Department, "
" Salary FROM employee ORDER BY empNo",DB);
if (qryModel->lastError().isValid())
{
QMessageBox::critical(this, "错误", "数据表查询错误,错误信息\n"
+qryModel->lastError().text());
return;
}
//2. 设置字段显示标题
QSqlRecord rec=qryModel->record(); //获取一个空记录,为了获取字段序号
qryModel->setHeaderData(rec.indexOf("empNo"), Qt::Horizontal, "工号");
qryModel->setHeaderData(rec.indexOf("Name"), Qt::Horizontal, "姓名");
qryModel->setHeaderData(rec.indexOf("Gender"), Qt::Horizontal, "性别");
qryModel->setHeaderData(rec.indexOf("Birthday"), Qt::Horizontal, "出生日期");
qryModel->setHeaderData(rec.indexOf("Province"), Qt::Horizontal, "省份");
qryModel->setHeaderData(rec.indexOf("Department"), Qt::Horizontal, "部门");
qryModel->setHeaderData(rec.indexOf("Salary"), Qt::Horizontal, "工资");
//3. 创建选择模型
selModel=new QItemSelectionModel(qryModel,this);
connect(selModel,&QItemSelectionModel::currentRowChanged,this, &MainWindow::do_currentRowChanged);
ui->tableView->setModel(qryModel);
//4. 创建数据映射
dataMapper= new QDataWidgetMapper(this);
dataMapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit);
dataMapper->setModel(qryModel);
//界面组件与数据模型的具体字段之间的映射
dataMapper->addMapping(ui->dbSpinEmpNo, rec.indexOf("empNo"));
dataMapper->addMapping(ui->dbEditName, rec.indexOf("Name"));
dataMapper->addMapping(ui->dbComboSex, rec.indexOf("Gender"));
dataMapper->addMapping(ui->dbEditBirth, rec.indexOf("Birthday"));
dataMapper->addMapping(ui->dbComboProvince, rec.indexOf("Province"));
dataMapper->addMapping(ui->dbComboDep, rec.indexOf("Department"));
dataMapper->addMapping(ui->dbSpinSalary, rec.indexOf("Salary"));
dataMapper->toFirst(); //移动到首记录
record函数不带参数可以获取字段名称,想要获取对应记录的字段对应值,可以参考以下:
QSqlRecord rec1=qryModel->record(2);
QVariant vr = rec1.value("Name");
QString qs = vr.toString();
qDebug() << qs;
使用ui->tableView->setSelectionModel(selModel);语句将界面显示与模型绑定在一起。
dataMapper将UI中的一系列界面组件映射到一条记录的不同字段,便设置显示为第一条记录的数据内容。
ui->tableView->setSelectionModel(selModel);设置了选择模型,当选择的行发生改变时候会进入以下槽函数:
void MainWindow::do_currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous)
{
Q_UNUSED(previous);
if (!current.isValid())
{
ui->dbLabPhoto->clear();
ui->dbEditMemo->clear();
return;
}
dataMapper->setCurrentModelIndex(current); //设置当前行
// dataMapper->setCurrentIndex(current.row()); //这个也可以
bool first=(current.row()==0); //是否首记录
bool last=(current.row()==qryModel->rowCount()-1); //是否尾记录
ui->actRecFirst->setEnabled(!first); //更新使能状态
ui->actRecPrevious->setEnabled(!first);
ui->actRecNext->setEnabled(!last);
ui->actRecLast->setEnabled(!last);
int curRecNo=selModel->currentIndex().row();
QSqlRecord curRec=qryModel->record(curRecNo); //获取当前记录
int empNo=curRec.value("EmpNo").toInt(); //主键字段
QSqlQuery query(DB); //查询某个empNo的Memo和Photo字段的数据
query.prepare("select EmpNo, Memo, Photo from employee where EmpNo = :ID");
query.bindValue(":ID",empNo);
query.exec();
query.first();
QVariant va=query.value("Photo");
if (!va.isValid()) //图片字段内容为空
ui->dbLabPhoto->clear();
else //显示图片
{
QByteArray data=va.toByteArray();
QPixmap pic;
pic.loadFromData(data);
ui->dbLabPhoto->setPixmap(pic.scaledToWidth(ui->dbLabPhoto->size().width()));
}
QVariant va2=query.value("Memo"); //显示备注
ui->dbEditMemo->setPlainText(va2.toString());
}
在槽函数中获取当前选择的记录,并设置dataMapper,选择的记录条在其他组件中同步更新,获取该记录的一些数据,然后用一个 QSqlQuery 变量 query 运行查询语句,查询对应EmpNo号对应记录的BLOB类型数据,并转化显示为图片。
记录的移动需要根据 QDataWidgetMapper 对象的当前行设置选择模型的当前行,这样才能使
QTableView组件和数据感知组件的当前行是同步的。
void MainWindow::on_actRecFirst_triggered()
{ //首记录
dataMapper->toFirst();
refreshTableView();
}
void MainWindow::on_actRecPrevious_triggered()
{ //前一记录
dataMapper->toPrevious();
refreshTableView();
}
void MainWindow::on_actRecNext_triggered()
{//后一记录
dataMapper->toNext();
refreshTableView();
}
void MainWindow::on_actRecLast_triggered()
{//尾记录
dataMapper->toLast();
refreshTableView();
}
//刷新tableView的当前行
void MainWindow::refreshTableView()
{
int index=dataMapper->currentIndex(); //dataMapper的当前行号
QModelIndex curIndex=qryModel->index(index,1); //为当前行创建模型索引
selModel->clearSelection(); //清空选择项
selModel->setCurrentIndex(curIndex,QItemSelectionModel::Select); //设置当前行
}
原文地址:https://blog.csdn.net/qq_46144191/article/details/144360245
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!