Я использую linux машину с psql 9 и QT 4.8. Я не могу использовать QSqlTableModel, потому что, когда таблица редактируется, модель создает ошибку P22, потому что она не может правильно обрабатывать массивы psql. Поэтому я пытаюсь использовать QsqlqueryModel. Мне нужна таблица для обновления базы данных с помощью кнопки отправки. В настоящее время я могу обновить базу данных с помощью кнопки отправки, но таблица возвращается к исходным данным запроса при вводе данных и последующем вводе или вводе. Я хочу, чтобы отредактированные данные оставались на столе.
//Main class for the QSqlQueryModel
EditableSqlModel::EditableSqlModel(QObject *parent)
: QSqlQueryModel(parent)
{
queryDatabase();
}
Qt::ItemFlags EditableSqlModel::flags(
const QModelIndex &index) const
{
Qt::ItemFlags flags = QSqlQueryModel::flags(index);
if (index.column() == 1 || index.column() == 2)
flags |= Qt::ItemIsEditable;
return flags;
}
bool EditableSqlModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.column() < 1 || index.column() > 2)
return false;
qDebug() << value << endl;
if(role == Qt::EditRole){
QModelIndex primaryKeyIndex = QSqlQueryModel::index(index.row(), 0);
int id = data(primaryKeyIndex).toInt();
bool ok;
cout << index.column() << endl;
switch(index.column()) {
case 1:
ok = setServiceType(id, value.toString());
emit dataChanged(index,index);
break;
case 2:
ok = setServicedBy(id, value.toString());
emit dataChanged(index, index);
break;
default:
ok = false;
}
return ok;
}
return false;
}
void EditableSqlModel::queryDatabase()
{
setQuery("select id,type,by,date,duration,date from hist order by date ASC limit 1000");
setHeaderData(0, Qt::Horizontal, QObject::tr("ID"));
setHeaderData(1, Qt::Horizontal, QObject::tr("Type"));
setHeaderData(2, Qt::Horizontal, QObject::tr(" By"));
setHeaderData(3, Qt::Horizontal, QObject::tr("Date"));
setHeaderData(4, Qt::Horizontal, QObject::tr("Duration"));
setHeaderData(5, Qt::Horizontal, QObject::tr("State"));
}
bool EditableSqlModel::setType(int vId, const QString &type)
{
QByteArray array = type.toLocal8Bit();
char* buffer = array.data();
char sql[4092];
QSqlQuery query;
sprintf(sql,"update hist set type = '%s' where id = %d",buffer,vId);
string val(sql);
queries.push_back(val);
return true;
}
bool EditableSqlModel::setBy(int vId, const QString &serviced)
{
QByteArray array = serviced.toLocal8Bit();
char* buffer = array.data();
char sql[4092];
QSqlQuery query;
sprintf(sql,"update hist set by = '%s' where id = %d",buffer,vId);
string val(sql);
queries.push_back(val);
return true;
}
void EditableSqlModel::writeToDatabase(){
QSqlQuery query;
for (it = queries.begin(); it != queries.end(); ++it){
string val = *it;
char sql[val.size() + 1];
strcpy(sql,val.c_str());
query.prepare(sql);
query.exec();
if (query.lastError().isValid())
qDebug() << "query exec" << query.lastError();
qDebug("%s" , query.lastQuery().toStdString().c_str());
}
cout << "Database updated" << endl;
queryDatabase();
}
//Mainwindow file
MainWindow::MainWindow(const QString &tableName, QWidget *parent):
QWidget(parent)
{
model = new EditableSqlModel(this);
view = new QTableView;
view->setModel(model);
view->resizeColumnsToContents();
submitButton = new QPushButton(tr("Submit"));
submitButton->setDefault(true);
newrowButton = new QPushButton(tr("&New"));
quitButton = new QPushButton(tr("Quit"));
buttonBox = new QDialogButtonBox(Qt::Vertical);
buttonBox->addButton(submitButton, QDialogButtonBox::ActionRole);
buttonBox->addButton(newrowButton, QDialogButtonBox::ActionRole);
buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);
createConnections();
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addWidget(view);
mainLayout->addWidget(buttonBox);
setLayout(mainLayout);
setWindowTitle(tr("Qt Table"));
}
void MainWindow:: submit(){
qDebug("Writing to database");
model->writeToDatabase();
}
void MainWindow::createConnections(){
connect(submitButton, SIGNAL(clicked()), this, SLOT(submit()));
connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));
connect(newrowButton, SIGNAL(clicked()), model, SLOT(addRow()));
}