Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

ComboBox delegate on QSqlRelationalTableModel: setModelData?



  • Hi,

    I'm fairly new to Qt and the whole C++ stuff and need a little help. I think the following is a common issue, but I couldn't find the last part of the puzzle so I appreciate any help or push in the right direction.

    I'm writing a database frontend applikation with mariaDB/mySQL backend and try to use the QSqlRelationalTableModel combined with a combo box delegate. The combo box delegate shows a list of size units, picked from a sperate table in the db.

    It works this far:

    • the table is shown
    • the unit-indexes are resolved to the units
    • the combo box is shown on click with all available options from the db

    What doesn't work is writing the chosen entry from the combo box back to the DB because I haven't figured out how to get the unit-index from the DB to feed "model->setData" the correct value.

    Here is my setModelData in comboboxdelegate.cpp

    unit table example:

    vpe_index | unit
    1         |  kg
    2         |  g
    3         |  l
    4         |  ml
    5         |  pcs.
    ...
    
    void comboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {
        if(QComboBox *cb = qobject_cast<QComboBox*>(editor)) {
    
            QString cbText = cb->currentText(); // text in combo box == text in db
            int cbIndex = cb->currentIndex(); // index in combo box
    
            int vpe_index =  ??? // index in db
    
            model->setData(index, vpe_index , Qt::EditRole);
        } else {
            QStyledItemDelegate::setModelData(editor, model, index);
        }
    }
    

    So I can get the current text from the combo box. But then? Do I have to execute another query on the db or is there a better way?

    in the delegate class I have access to

    QSqlQueryModel comboBoxModel
    

    which has the query "SELECT unit, vpe_index FROM vpe_typen" prepared and executed in my mainwindow.cpp.
    I'm sure there is a way to make use of this, but I don't know how.



  • Ok, I have figured it out by myself. The key was looking at the comboBoxModel->data and getting the index from rows and coloumns. That's my solution:

    void comboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {
        if(QComboBox *cb = qobject_cast<QComboBox*>(editor)) {
            QString cbText = cb->currentText();
            int vpe_index = -1;
    
            for (int row = 0; row < comboBoxModel->rowCount() ; row++) {
                if (comboBoxModel->data(comboBoxModel->index(row, 0)) == cbText){
                    vpe_index = comboBoxModel->data(comboBoxModel->index(row, 1)).toInt();
                }
            }
            if (vpe_index == -1) {
                qDebug() << "Index not found";
            }
            else {
                qDebug() << "Index set: " << model->setData(index, vpe_index, Qt::EditRole);
            }
    
        } else {
            QStyledItemDelegate::setModelData(editor, model, index);
        }
    }