Qt-Как реализовать QSqlQueryModel для чтения и записи?

Я переклассифицировал QSqlQueryModel :: setData () и QSqlQueryModel :: flags (), и теперь я могу редактировать эту модель, но здесь что-то не так:

введите описание изображения здесь

Я редактирую четвертое поле в записи, но впоследствии четвертое поле и последние изменяют его содержимое на одно и то же:

введите описание изображения здесь

Вот мой Scoremodel.cpp:

#include <QtSql>
#include "scoremodel.h"#include "mainwindow.h"    //MainWindow::sqlToQueryScore
#include <QDebug>

ScoreModel::ScoreModel(QObject *parent)
: QSqlQueryModel(parent)
{
}

Qt::ItemFlags ScoreModel::flags(
const QModelIndex &index) const
{
Qt::ItemFlags flags = QSqlQueryModel::flags(index);
if (index.column() != 0 && index.column() != 11)
flags |= Qt::ItemIsEditable;
return flags;
}

bool ScoreModel::setData(const QModelIndex &index, const QVariant &value, int /* role */)
{
if (index.column() == 0 || index.column() == 11)
return false;

QModelIndex primaryKeyIndex = QSqlQueryModel::index(index.row(), 0);
int id = data(primaryKeyIndex).toInt();
qDebug()<<"id:"<<id;
clear();

bool ok;
switch(index.column()){
case 1:
ok = setYear(id,value.toString());
case 2:
ok = setStudentName(id,value.toString());
case 3:
ok = setStudentClass(id,value.toString());
case 4:
ok = setTestTime(id,value.toString());
case 5:
ok = setTestSubject(id,value.toString());
case 6:
ok = setTestType(id,value.toString());
case 7:
ok = setTestScore(id,value.toString());
case 8:
ok = setStudyPeriod(id,value.toString());
case 9:
ok = setTestContent(id,value.toString());
case 10:
ok = setTeacherRemark(id,value.toString());
default:
ok = false;
}
refresh();
return ok;
}void ScoreModel::refresh()
{
qDebug()<<"sqlToQueryScore in refresh:"<<MainWindow::sqlToQueryScore;
setQuery(MainWindow::sqlToQueryScore);
setHeaderData(0, Qt::Horizontal, tr("序号"));
setHeaderData(1, Qt::Horizontal, tr("年份"));
setHeaderData(2, Qt::Horizontal, tr("学生姓名"));
setHeaderData(3, Qt::Horizontal, tr("学生班级"));
setHeaderData(4, Qt::Horizontal, tr("测试时间"));
setHeaderData(5, Qt::Horizontal, tr("测试科目"));
setHeaderData(6, Qt::Horizontal, tr("测试类型"));
setHeaderData(7, Qt::Horizontal, tr("测试成绩"));
setHeaderData(8, Qt::Horizontal, tr("学习周期"));
setHeaderData(9, Qt::Horizontal, tr("测试内容"));
setHeaderData(10, Qt::Horizontal, tr("教师评语"));
setHeaderData(11, Qt::Horizontal, tr("数据插入时间"));

}

bool ScoreModel::setYear(int id, const QString &year){
QSqlQuery query;
query.prepare("update test_score set year = ? where id = ?");
query.addBindValue(year);
query.addBindValue(id);
return query.exec();
}
bool ScoreModel::setStudentName(int id, const QString &studentName){
QSqlQuery query;
query.prepare("update test_score set student_name = ? where id = ?");
query.addBindValue(studentName);
query.addBindValue(id);
return query.exec();
}
bool ScoreModel::setStudentClass(int id,const QString &studentClass){
QSqlQuery query;
query.prepare("update test_score set student_class = ? where id = ?");
query.addBindValue(studentClass);
query.addBindValue(id);
return query.exec();
}
bool ScoreModel::setTestTime(int id,const QString &testTime){
QSqlQuery query;
query.prepare("update test_score set test_time = ? where id = ?");
query.addBindValue(testTime);
query.addBindValue(id);
return query.exec();
}
bool ScoreModel::setTestSubject(int id,const QString &testSubject){
QSqlQuery query;
query.prepare("update test_score set test_subject = ? where id = ?");
query.addBindValue(testSubject);
query.addBindValue(id);
return query.exec();
}
bool ScoreModel::setTestType(int id,const QString &testType){
QSqlQuery query;
query.prepare("update test_score set test_type = ? where id = ?");
query.addBindValue(testType);
query.addBindValue(id);
return query.exec();
}
bool ScoreModel::setTestScore(int id,const QString &testScore){
QSqlQuery query;
query.prepare("update test_score set test_score = ? where id = ?");
query.addBindValue(testScore);
query.addBindValue(id);
return query.exec();
}
bool ScoreModel::setStudyPeriod(int id,const QString &studyPeriod){
QSqlQuery query;
query.prepare("update test_score set study_period = ? where id = ?");
query.addBindValue(studyPeriod);
query.addBindValue(id);
return query.exec();
}
bool ScoreModel::setTestContent(int id,const QString &testContent){
QSqlQuery query;
query.prepare("update test_score set test_content = ? where id = ?");
query.addBindValue(testContent);
query.addBindValue(id);
return query.exec();
}
bool ScoreModel::setTeacherRemark(int id,const QString &teacherRemark){
QSqlQuery query;
query.prepare("update test_score set teacher_remark = ? where id = ?");
query.addBindValue(teacherRemark);
query.addBindValue(id);
return query.exec();
}

Я отлаживал его долгое время. И если вы можете мне помочь, я буду очень признателен.
Спасибо!

2

Решение

Я попытался уменьшить код, который показывает, помимо реализации решения, которое вы хотите, как я покажу ниже, с другой стороны, я бы порекомендовал использовать QSqlTableModel,

#include <QApplication>
#include <QMessageBox>
#include <QSqlQuery>
#include <QSqlQueryModel>
#include <QSqlRecord>
#include <QSqlError>
#include <QSqlTableModel>
#include <QTableView>

class SqlQueryModel: public QSqlQueryModel{
public:
using QSqlQueryModel::QSqlQueryModel;
Qt::ItemFlags flags(const QModelIndex &index) const {
return QSqlQueryModel::flags(index) | Qt::ItemIsEditable;
}
bool setData(const QModelIndex &index, const QVariant &value, int role){
if (index.isValid() && role == Qt::EditRole) {
QSqlQuery qry;
qry.prepare(QString("update test_score set %1 = ? where id = ?").arg(record().fieldName(index.column())));
qry.addBindValue(value);
qry.addBindValue(query().value(record().indexOf("id")));
if(!qry.exec())
return false;
setQuery(query().lastQuery());
return true;
}
return false;
}
};

static bool createConnection()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(":memory:");
if (!db.open()) {
QMessageBox::critical(nullptr, QObject::tr("Cannot open database"),
QObject::tr("Unable to establish a database connection.\n""This example needs SQLite support. Please read ""the Qt SQL driver documentation for information how ""to build it.\n\n""Click Cancel to exit."), QMessageBox::Cancel);
return false;
}

QSqlQuery query;
query.exec("create table test_score (id int primary key, student_name varchar(20), student_class varchar(20))");
query.exec("insert into test_score values(101, 'name1', 'Young')");
query.exec("insert into test_score values(102, 'name2', 'Holand')");
query.exec("insert into test_score values(103, 'Lars', 'Gordon')");
query.exec("insert into test_score values(104, 'Roberto', 'Robitaille')");
query.exec("insert into test_score values(105, 'Maria', 'Papadopoulos')");
return true;
}int main(int argc, char *argv[])
{
QApplication a(argc, argv);
if(!createConnection())
return -1;
QTableView view;
SqlQueryModel model;
model.setQuery("SELECT * FROM test_score");
view.setModel(&model);
view.show();
return a.exec();
}

Если присмотреться к вашему коду, ошибка вызвана отсутствием break в каждом case,

...
switch(index.column()){
case 1:
ok = setYear(id,value.toString());
break; // <---
case 2:
ok = setStudentName(id,value.toString());
break; // <---
case 3:
...
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]