QSqlRelationalTableModel Dopdown List for Field



  • Hello,
    I want in a qtableview (DamTV) a Dropdown-Listbox for a special column.

    QSqlRelationalTableModel Dams;
    Dams.setEditStrategy(QSqlTableModel::OnFieldChange);
    Dams.setTable(tblDamageTemplate);
    Dams.setRelation(4, QSqlRelation("qlkp_DamPart", "ID", "SCDesc"));
    ui->DamTV->setModel(&Dams);
    ui->DamTV->setItemDelegateForColumn(4, new QSqlRelationalDelegate(this));
    Dams.select();
    

    After select all is correct, I see instead of the primary key the lookup text in column 4.
    When I select a field and leave the field I see the primary key (ID).

    Why is that ? Why changes the editor the view representation of the data ?
    This should be independent when I understand the concept correctly.


  • Lifetime Qt Champion

    Hi,,

    Where are you using this code ?



  • @SGaist
    In the constructor of the dialog after ui->setupUi(this);
    QSqlRelationalTableModel Dams; is of course in the header of the dialog.


  • Lifetime Qt Champion

    Which OS and Qt version ?



  • Qt 5.6.0 32-bit, MSVC 2015, Windows 10 64-bit

    If found the code for the QSqlRelationalDelegate, have made a renamed copy of it for testing.

    class QSqlRelationalDelegate2: public QItemDelegate
    {
    public:
        explicit QSqlRelationalDelegate2(QObject *aParent = 0)
            : QItemDelegate(aParent)  {}
        ~QSqlRelationalDelegate2()  {}
    
        QWidget *createEditor(QWidget *aParent,
                              const QStyleOptionViewItem &option,
                              const QModelIndex &index) const
        {
            const QSqlRelationalTableModel *sqlModel
                    = qobject_cast<const QSqlRelationalTableModel *>(index.model());
            QSqlTableModel *childModel = sqlModel ? sqlModel->relationModel(index.column()) : 0;
            if (!childModel)
                return QItemDelegate::createEditor(aParent, option, index);
    
            QComboBox *combo = new QComboBox(aParent);
            combo->setModel(childModel);
            combo->setModelColumn(childModel->fieldIndex(sqlModel->relation(
                                    index.column()).displayColumn()));
            combo->installEventFilter(const_cast<QSqlRelationalDelegate2 *>(this));
    
            return combo;
        }
    
        void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
        {
            if (!index.isValid())
                return;
    
            QSqlRelationalTableModel *sqlModel = qobject_cast<QSqlRelationalTableModel *>(model);
            QSqlTableModel *childModel = sqlModel ? sqlModel->relationModel(index.column()) : 0;
            QComboBox *combo = qobject_cast<QComboBox *>(editor);
            if (!sqlModel || !childModel || !combo) {
                QItemDelegate::setModelData(editor, model, index);
                return;
            }
    //        QSqlRelation newrel(sqlModel->relation(index.column()));
    
            int currentItem = combo->currentIndex();
            int childColIndex = childModel->fieldIndex(sqlModel->relation(index.column()).displayColumn());
            int childEditIndex = childModel->fieldIndex(sqlModel->relation(index.column()).indexColumn());
    
            QString dd=childModel->data(childModel
                    ->index(currentItem, childColIndex), Qt::DisplayRole).toString();
    
            sqlModel->setData(index,
                    childModel->data(childModel->index(currentItem, childColIndex),
                    Qt::DisplayRole), Qt::DisplayRole);
            sqlModel->setData(index,
                    childModel->data(childModel->index(currentItem, childEditIndex),
                    Qt::EditRole), Qt::EditRole);
    //        sqlModel->setRelation(index.column(), newrel);
    //        sqlModel->dataChanged(index, index,
    //                QVector<int>()<<Qt::DisplayRole<<Qt::EditRole);
        }
        void paint(QPainter* painter,   const QStyleOptionViewItem& opt,
                   const QModelIndex& index) const
        {
            QString s=index.data(Qt::DisplayRole).toString();
            QStyleOptionViewItem so=opt;
            drawDisplay(painter, so, so.rect, s);
            return;
        }
    };
    

    Not even the overwriting of the paint function help. Should not have the delegate the control for the painting always ?

    In the setModelData function the last command

            sqlModel->setData(index,
                    childModel->data(childModel->index(currentItem, childEditIndex),
                    Qt::EditRole), Qt::EditRole);
    

    makes the problem. After write back the data from the widget to the model I get the view shows the foreign key and not its lookup.



  • I found the delegate has indeed ever the control for the painting. Before editing all works.
    The problem is that after setModelData both the Display- and Editrole give always the foreign key for the changed cell.

    QString s1=index.data(Qt::DisplayRole).toString();
    QString s2=index.data(Qt::EditRole).toString();


  • Lifetime Qt Champion

    Can you provide a minimal compilable example that reproduce that behaviour ?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.