updating database with custom delegate
Hi!
I have a QTableWidget linked to a custom delegate, which has a QDateEdit column (0) and 2 QComboBox columns (1 and 3). I also have a QSqlTableModel which is conected to a table inside an MS access DB (used for simplicity). I can load the data for the QTableWidget correctly from the Db, but when i change any field in the QTableWidget and make the changes to the model, the DB doesnt update (i call submitAll()). I think that the problem must be soemthing about the QSqlModel and the model of the QTableWidget (i cant call QTableWidget::setModel(), as it is a private func. - at least that says the compiler).
This is my code:
Code:
#include "comprasDelegate.h"
sqlQtPro
::sqlQtPro(QWidget *parent
){
ui.setupUi(this);
this->loadAccessDatabase("base2.mdb");
this->loadModels();
dialogoProveedores=new dialogProvedores(this, modelProveedores);
ui.botTerminarCompra->setVisible(false);
//prueba combo
ui.
viewCompras->setHorizontalHeaderLabels
(QStringList() << tr
("Fecha") << tr("Proveedor") << tr("Importe")
<< tr("IVA") << tr("Total"));
this->rellenarListaCompras();
QObject::connect(ui.
actionProveedores,
SIGNAL(triggered
()),
this, SLOT(showProveedores(void)));
QObject::connect(ui.
botAddCompra,
SIGNAL(clicked
()),
this,
SLOT(addCompras
(void)));
QObject::connect(this
->mComprasDelegate,
SIGNAL(commitData
(QWidget*)),
this,
SLOT(updateComprasTable
()));
}
int sqlQtPro
::loadAccessDatabase(QString fileName
) {
db.setDatabaseName("DRIVER={Microsoft Access Driver (*.mdb)};FIL={MS Access};DBQ="+fileName.toLatin1());
if (!db.open()) {
QMessageBox::critical(0, qApp
->tr
("Cannot open database"),
qApp->tr("Imposible establecer conexión con la Base de Datos ODBC.\n\n"
"Presiona Cancelar para salir."),
QMessageBox::Cancel);
return false;
}else
{
return true;
}
}
void sqlQtPro::loadModels()
{
modelCompras->setTable("Compras");
modelCompras->select();
modelCompras
->setHeaderData
(0, Qt
::Horizontal,
QObject::tr("Fecha"));
modelCompras
->setHeaderData
(1, Qt
::Horizontal,
QObject::tr("Proveedor"));
modelCompras
->setHeaderData
(2, Qt
::Horizontal,
QObject::tr("Importe"));
modelCompras
->setHeaderData
(3, Qt
::Horizontal,
QObject::tr("IVA"));
modelCompras
->setHeaderData
(4, Qt
::Horizontal,
QObject::tr("Importe final"));
//ui.viewCompras->setModel(modelCompras);
}
void sqlQtPro::rellenarListaCompras()
{
mComprasDelegate = new ComprasDelegate(this);
ui.viewCompras->setItemDelegate(mComprasDelegate);
for (int i=0; i<modelProveedores->rowCount(); ++i)
mComprasDelegate->insertProveedor(modelProveedores->index(i,0).data().toString());
for (int i=0; i<modelCompras->rowCount();++i)
{
int row=ui.viewCompras->rowCount();
ui.viewCompras->setRowCount(row+1);
ui.viewCompras->setItem(i, 0, item0);
ui.viewCompras->setItem(i, 1, item1);
ui.viewCompras->setItem(i, 2, item2);
ui.viewCompras->setItem(i, 3, item3);
ui.viewCompras->setItem(i, 4, item4);
ui.viewCompras->openPersistentEditor(item0);
ui.viewCompras->openPersistentEditor(item1);
ui.viewCompras->openPersistentEditor(item3);
}
ui.viewCompras->resizeColumnsToContents();
ui.viewCompras->sortByColumn(0);
}
void sqlQtPro::updateComprasTable()
{
if(!modelCompras->submitAll())
tr("The database reported an error: %1").arg(modelCompras->lastError().text()));
//else modelCompras->database().commit();
}
comprasDelegate.cpp
Code:
#include "ComprasDelegate.h"
ComprasDelegate
::ComprasDelegate(QObject *parent
){
}
{
if((index.column()==1)||(index.column()==3))
{
if (index.column() == 1) {
comboBox->addItems(sListaProveedores);
} else if (index.column() == 3) {
comboBox->addItem(tr("7%"));
comboBox->addItem(tr("16%"));
}
connect(comboBox, SIGNAL(activated(int)), this, SLOT(emitCommitData()));
retWidget=comboBox;
}else if (index.column()==0)
{
edit->setDisplayFormat("dd/MM/yyyy");
connect(edit,
SIGNAL(dateChanged
(QDate)),
this,
SLOT(emitCommitData
()));
retWidget=edit;
}
return retWidget;
}
void ComprasDelegate
::setEditorData(QWidget *editor,
{
if (index.column()==0)
{
QDateEdit * edit
=qobject_cast<QDateEdit
*>
(editor
);
if(!edit) return;
edit->blockSignals(true);
edit
->setDate
(QDate::fromString(index.
model()->data
(index
).
toString(),
"yyyy-MM-ddT00:00:00"));
edit->blockSignals(false);
}
else if (index.column()==1)
{
QComboBox *comboBox
= qobject_cast<QComboBox
*>
(editor
);
if (!comboBox)
return;
int pos = comboBox->findText(index.model()->data(index).toString(),Qt::MatchExactly);
comboBox->setCurrentIndex(pos);
}
}
{
if (index.column()==0)
{
QDateEdit * edit
=qobject_cast<QDateEdit
*>
(editor
);
if(!edit) return;
model->setData(index,"pp");
qApp->tr("set data '"+edit->date().toString("dd/MM/yyyy").toLatin1()+"'\n\n"
"Presiona Cancelar para salir."),
QMessageBox::Cancel);
if(!model->setData(index,edit->date().toString("dd/MM/yyyy")))
qApp->tr("'error introd. fecha'\n\n"
"Presiona Cancelar para salir."),
QMessageBox::Cancel);
//edit->setDate(QDate::fromString(index.model()->data(index).toString(),"dd/MM/yyyy"));
}
else if (index.column()==1)
{
QComboBox *comboBox
= qobject_cast<QComboBox
*>
(editor
);
if (!comboBox)
return;
if(!model->setData(index, comboBox->currentText()))
qApp->tr("'error introd. data combo'\n\n"
"Presiona Cancelar para salir."),
QMessageBox::Cancel);
}
}
void ComprasDelegate::emitCommitData()
{
emit commitData(qobject_cast<QWidget *>(sender()));
/*QMessageBox::critical(0, qApp->tr("Fecha"),
qApp->tr("'commit data'\n\n"
"Presiona Cancelar para salir."), QMessageBox::Cancel);*/
}
void ComprasDelegate
::insertProveedor(QString proveedor
) {
sListaProveedores.push_back(proveedor);
}
Any idea??
Thx!!
J.
Re: updating database with custom delegate
Use QTableView to show contents of a model. QTableWidget has a built-in model which is not supposed to be changed.
From QTableWidget docs:
Quote:
The QTableWidget class provides an item-based table view with a default model.
...
If you want a table that uses your own data model you should use QTableView rather than this class.
Re: updating database with custom delegate
This means that i cant use QcomboBox or other control on a table (item or widget) and a DB?
Could i copy the data from the QTableWidget's model to my own model?? (tableView doesnt support widgets on it, im correct??)
Thx!!
J.
Re: updating database with custom delegate
QTableView uses a delegate and supports widgets just like QTableWidget does. It makes no sense to copy data from an SQL model to QTableWidget when you can simply set the SQL model as QTableView's model and it will show the data for you out of the box. Please take a look at SQL and Model/View examples shipped with Qt.
Re: updating database with custom delegate
Thx, copying the model works, but yours is a better solution... ill give it a try!!!
:D
J.