Delegate for QSqlTableModel / QTableView - problem tabbing from one row to next when editing
-
Good evening,
In order to learn more about database handling and Qt, I have set up a simple database in mysql and I am working on being able to edit existing and new records. It is working, but the behaviour is strange when I tab out of the row and into the next. If I press return while still in the row being edited, everything works as planned. If I tab out of the last field into the next row, it picks up the data from the next row and stores it. First of all, I had a suspicion this is a delegate issue, as I had the QSqlRelationalTableDelegate set up originally. I have subsequently removed the setDelegate() call, hoping that default behaviour would be correct. Alternatively, do I need to set up a signal/slot to catch the movement out of the row, then update the database?
Here is the code:
nametablewindow.h:
@
#ifndef NAMETABLEWINDOW_H
#define NAMETABLEWINDOW_H#include <QtGui>
#include <QtSql>enum { // Field names
names_id = 0,
names_firstname = 1,
names_surname = 2,
names_address_id = 3,
names_comment = 4
};class NameTableWindow: public QWidget
{
Q_OBJECT
public:
NameTableWindow(QWidget *parent = 0);
//virtual bool insertRows(int row, int count, const QModelIndex & parent = QModelIndex());
signals:public slots:
void insert(void);
void remove(void);private:
QSqlTableModel *namesModel;QTableView *namesView; QLabel *namesLabel; QDialogButtonBox *buttonBox;
};
#endif // NAMETABLEWINDOW_H
@nametablewindow.cpp
@
#include "nametablewindow.h"NameTableWindow::NameTableWindow(QWidget *parent) :
QWidget(parent)
{
// Create model and load data query
namesModel = new QSqlTableModel(this);
namesModel->setTable("names");
namesModel->setEditStrategy(QSqlTableModel::OnRowChange);// Set up the headers namesModel->setHeaderData(names_id,Qt::Horizontal, tr("id")); namesModel->setHeaderData(names_firstname, Qt::Horizontal, tr("First Name")); namesModel->setHeaderData(names_surname,Qt::Horizontal, tr("Surname")); namesModel->setHeaderData(names_address_id, Qt::Horizontal, tr("address id")); namesModel->setHeaderData(names_comment, Qt::Horizontal, tr("Comment")); // Load the table data namesModel->select(); // Create the view namesView = new QTableView(this); namesView->setModel(namesModel); namesView->setEditTriggers(QAbstractItemView::AnyKeyPressed | QAbstractItemView::DoubleClicked); // Removed - this delegate is for QSqlRelationalTableModel //namesView->setItemDelegate(new QSqlRelationalDelegate(this)); namesView->setSelectionMode(QAbstractItemView::SingleSelection); namesView->setSelectionBehavior(QAbstractItemView::SelectRows); // select row not cell namesView->hideColumn(names_id); namesView->resizeColumnsToContents(); namesView->horizontalHeader()->setStretchLastSection(true); // Set up Label namesLabel = new QLabel(tr("Names in Table")); namesLabel->setBuddy(namesView); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(namesLabel); layout->addWidget(namesView); connect(namesView, SIGNAL(activated(QModelIndex)), namesModel, SLOT(submitAll())); buttonBox = new QDialogButtonBox; QPushButton *addButton = buttonBox->addButton(tr("Add"),QDialogButtonBox::ActionRole); QPushButton *rmButton = buttonBox->addButton(tr("Delete"),QDialogButtonBox::ActionRole); buttonBox->addButton(QDialogButtonBox::Ok); layout->addWidget(buttonBox); connect(rmButton, SIGNAL(clicked()), this, SLOT(remove())); connect(addButton, SIGNAL(clicked()), this, SLOT(insert())); connect(buttonBox, SIGNAL(accepted()), this, SLOT(close())); // SLOT(accept())); setLayout(layout); setWindowTitle(tr("Names Table")); namesView->setCurrentIndex(namesModel->index(0,0));
}
void NameTableWindow::insert()
{
int row = namesView->currentIndex().row();if (row < 0) // no record selected - add to end row = namesModel->rowCount(); namesModel->insertRows(row,1); qDebug("rowCount(): %d", row); QModelIndex index = namesModel->index(row,0); namesView->setCurrentIndex(index); namesView->edit(index);
}
void NameTableWindow::remove()
{
int row = namesView->currentIndex().row();
namesModel->removeRow(row);
}
@...and for completion, main.cpp:
@
#include <QApplication>
#include "mainwindow.h"
#include "database.h"
#include <iostream>
#include "nametablewindow.h"int main(int argc, char *argv[])
{
QApplication a(argc, argv);// The database connection needs to be made before any of the models are set // up, otherwise you will get "Database not open" errors and no data if (!createConnection()) { std::cerr << "Unable to open database" << std::endl; return 1; } NameTableWindow namesWindow; namesWindow.show(); return a.exec();
}
@I can post the remaining files if you want to have a go with running it yourself.
I am sure I am missing something simple - I look forward to your help!
Thanks!