Results 1 to 5 of 5

Thread: updating database with custom delegate

  1. #1
    Join Date
    Jul 2007
    Posts
    9
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default 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:

    Qt Code:
    1. #include "comprasDelegate.h"
    2.  
    3.  
    4. sqlQtPro::sqlQtPro(QWidget *parent)
    5. : QMainWindow(parent)
    6. {
    7. ui.setupUi(this);
    8.  
    9. this->loadAccessDatabase("base2.mdb");
    10. this->loadModels();
    11.  
    12. dialogoProveedores=new dialogProvedores(this, modelProveedores);
    13.  
    14. ui.botTerminarCompra->setVisible(false);
    15.  
    16. //prueba combo
    17. ui.viewCompras->setHorizontalHeaderLabels(QStringList() << tr("Fecha")
    18. << tr("Proveedor") << tr("Importe")
    19. << tr("IVA") << tr("Total"));
    20. this->rellenarListaCompras();
    21.  
    22. QObject::connect(ui.actionProveedores, SIGNAL(triggered()),
    23. this, SLOT(showProveedores(void)));
    24. QObject::connect(ui.botAddCompra, SIGNAL(clicked()),this, SLOT(addCompras(void)));
    25. QObject::connect(this->mComprasDelegate,SIGNAL(commitData(QWidget*)),this,SLOT(updateComprasTable()));
    26.  
    27. }
    28.  
    29. int sqlQtPro::loadAccessDatabase(QString fileName)
    30. {
    31. QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
    32. db.setDatabaseName("DRIVER={Microsoft Access Driver (*.mdb)};FIL={MS Access};DBQ="+fileName.toLatin1());
    33. if (!db.open()) {
    34. QMessageBox::critical(0, qApp->tr("Cannot open database"),
    35. qApp->tr("Imposible establecer conexión con la Base de Datos ODBC.\n\n"
    36.  
    37. "Presiona Cancelar para salir."), QMessageBox::Cancel);
    38. return false;
    39. }else
    40. {
    41. return true;
    42. }
    43. }
    44.  
    45. void sqlQtPro::loadModels()
    46. {
    47. modelCompras=new QSqlTableModel(this);
    48. modelCompras->setTable("Compras");
    49. modelCompras->setEditStrategy(QSqlTableModel::OnManualSubmit);
    50. modelCompras->select();
    51. modelCompras->setHeaderData(0, Qt::Horizontal, QObject::tr("Fecha"));
    52. modelCompras->setHeaderData(1, Qt::Horizontal, QObject::tr("Proveedor"));
    53. modelCompras->setHeaderData(2, Qt::Horizontal, QObject::tr("Importe"));
    54. modelCompras->setHeaderData(3, Qt::Horizontal, QObject::tr("IVA"));
    55. modelCompras->setHeaderData(4, Qt::Horizontal, QObject::tr("Importe final"));
    56.  
    57.  
    58. //ui.viewCompras->setModel(modelCompras);
    59.  
    60.  
    61. }
    62.  
    63.  
    64.  
    65.  
    66. void sqlQtPro::rellenarListaCompras()
    67. {
    68.  
    69. mComprasDelegate = new ComprasDelegate(this);
    70. ui.viewCompras->setItemDelegate(mComprasDelegate);
    71. for (int i=0; i<modelProveedores->rowCount(); ++i)
    72. mComprasDelegate->insertProveedor(modelProveedores->index(i,0).data().toString());
    73.  
    74. for (int i=0; i<modelCompras->rowCount();++i)
    75. {
    76. int row=ui.viewCompras->rowCount();
    77. ui.viewCompras->setRowCount(row+1);
    78. QTableWidgetItem *item0 = new QTableWidgetItem(modelCompras->index(i,0).data().toString());
    79. QTableWidgetItem *item1 = new QTableWidgetItem(modelCompras->index(i,1).data().toString());
    80. QTableWidgetItem *item2 = new QTableWidgetItem(modelCompras->index(i,2).data().toString());
    81. QTableWidgetItem *item3 = new QTableWidgetItem(modelCompras->index(i,3).data().toString());
    82. QTableWidgetItem *item4 = new QTableWidgetItem(modelCompras->index(i,4).data().toString());
    83. ui.viewCompras->setItem(i, 0, item0);
    84. ui.viewCompras->setItem(i, 1, item1);
    85. ui.viewCompras->setItem(i, 2, item2);
    86. ui.viewCompras->setItem(i, 3, item3);
    87. ui.viewCompras->setItem(i, 4, item4);
    88. ui.viewCompras->openPersistentEditor(item0);
    89. ui.viewCompras->openPersistentEditor(item1);
    90. ui.viewCompras->openPersistentEditor(item3);
    91.  
    92. }
    93. ui.viewCompras->resizeColumnsToContents();
    94. ui.viewCompras->sortByColumn(0);
    95. }
    96.  
    97. void sqlQtPro::updateComprasTable()
    98. {
    99. if(!modelCompras->submitAll())
    100. QMessageBox::warning(this, tr("Cached Table"),
    101. tr("The database reported an error: %1").arg(modelCompras->lastError().text()));
    102. //else modelCompras->database().commit();
    103. }
    To copy to clipboard, switch view to plain text mode 

    comprasDelegate.cpp
    Qt Code:
    1. #include "ComprasDelegate.h"
    2.  
    3. QStringList ComprasDelegate::sListaProveedores;
    4.  
    5. ComprasDelegate::ComprasDelegate(QObject *parent)
    6. : QItemDelegate(parent)
    7. {
    8. }
    9.  
    10. QWidget *ComprasDelegate::createEditor(QWidget *parent,
    11. const QStyleOptionViewItem & /* option */,
    12. const QModelIndex &index) const
    13. {
    14. QWidget* retWidget=NULL;;
    15. if((index.column()==1)||(index.column()==3))
    16. {
    17. QComboBox *comboBox = new QComboBox(parent);
    18. if (index.column() == 1) {
    19. comboBox->addItems(sListaProveedores);
    20. } else if (index.column() == 3) {
    21. comboBox->addItem(tr("7%"));
    22. comboBox->addItem(tr("16%"));
    23. }
    24. connect(comboBox, SIGNAL(activated(int)), this, SLOT(emitCommitData()));
    25. retWidget=comboBox;
    26. }else if (index.column()==0)
    27. {
    28. QDateEdit *edit= new QDateEdit(parent);
    29. edit->setDisplayFormat("dd/MM/yyyy");
    30. connect(edit, SIGNAL(dateChanged(QDate)), this, SLOT(emitCommitData()));
    31. retWidget=edit;
    32. }
    33. return retWidget;
    34. }
    35.  
    36. void ComprasDelegate::setEditorData(QWidget *editor,
    37. const QModelIndex &index) const
    38. {
    39. if (index.column()==0)
    40. {
    41. QDateEdit * edit=qobject_cast<QDateEdit*>(editor);
    42. if(!edit) return;
    43.  
    44. edit->blockSignals(true);
    45. edit->setDate(QDate::fromString(index.model()->data(index).toString(),"yyyy-MM-ddT00:00:00"));
    46. edit->blockSignals(false);
    47. }
    48. else if (index.column()==1)
    49. {
    50. QComboBox *comboBox = qobject_cast<QComboBox *>(editor);
    51. if (!comboBox)
    52. return;
    53.  
    54. int pos = comboBox->findText(index.model()->data(index).toString(),Qt::MatchExactly);
    55. comboBox->setCurrentIndex(pos);
    56. }
    57.  
    58.  
    59. }
    60.  
    61. void ComprasDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
    62. const QModelIndex &index) const
    63. {
    64. if (index.column()==0)
    65. {
    66. QDateEdit * edit=qobject_cast<QDateEdit*>(editor);
    67. if(!edit) return;
    68.  
    69. model->setData(index,"pp");
    70. QMessageBox::critical(0, qApp->tr("set data"),
    71. qApp->tr("set data '"+edit->date().toString("dd/MM/yyyy").toLatin1()+"'\n\n"
    72. "Presiona Cancelar para salir."), QMessageBox::Cancel);
    73. if(!model->setData(index,edit->date().toString("dd/MM/yyyy")))
    74. QMessageBox::critical(0, qApp->tr("Fecha"),
    75. qApp->tr("'error introd. fecha'\n\n"
    76. "Presiona Cancelar para salir."), QMessageBox::Cancel);
    77.  
    78. //edit->setDate(QDate::fromString(index.model()->data(index).toString(),"dd/MM/yyyy"));
    79. }
    80. else if (index.column()==1)
    81. {
    82. QComboBox *comboBox = qobject_cast<QComboBox *>(editor);
    83. if (!comboBox)
    84. return;
    85.  
    86. if(!model->setData(index, comboBox->currentText()))
    87. QMessageBox::critical(0, qApp->tr("Fecha"),
    88. qApp->tr("'error introd. data combo'\n\n"
    89. "Presiona Cancelar para salir."), QMessageBox::Cancel);
    90. }
    91.  
    92. }
    93.  
    94. void ComprasDelegate::emitCommitData()
    95. {
    96. emit commitData(qobject_cast<QWidget *>(sender()));
    97. /*QMessageBox::critical(0, qApp->tr("Fecha"),
    98. qApp->tr("'commit data'\n\n"
    99. "Presiona Cancelar para salir."), QMessageBox::Cancel);*/
    100. }
    101.  
    102. void ComprasDelegate::insertProveedor(QString proveedor)
    103. {
    104. sListaProveedores.push_back(proveedor);
    105. }
    To copy to clipboard, switch view to plain text mode 

    Any idea??

    Thx!!

    J.

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default 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:
    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.
    J-P Nurmi

  3. #3
    Join Date
    Jul 2007
    Posts
    9
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default 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.

  4. #4
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default 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.
    J-P Nurmi

  5. The following user says thank you to jpn for this useful post:

    Shaitan (17th July 2007)

  6. #5
    Join Date
    Jul 2007
    Posts
    9
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: updating database with custom delegate

    Thx, copying the model works, but yours is a better solution... ill give it a try!!!


    J.

Similar Threads

  1. Capture events in a custom delegate
    By vfernandez in forum Qt Programming
    Replies: 9
    Last Post: 19th March 2008, 06:33
  2. updating database
    By locus in forum Qt Programming
    Replies: 3
    Last Post: 27th January 2007, 06:54

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.