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

Automatically accept choice of QComboBox in a QStyledItemDelegate



  • Hello,
    I have a QComboBox as a QStyledItemDelegate in a ModelView
    Now I click a cell -> the combo box pops up -> I click my choice -> the combo box collapses.
    However afterwards I have to click somewhere else in the view (or press enter) to apply the change.
    How can I make it apply the change immediately?



  • Inside setEditorData, as last line, add:
    connect(combobox,QOverload<int>::of(&QComboBox::currentIndexChanged),this,std::bind(&QStyledItemDelegate::commitData,this,combobox));



  • Thanks for the hint, however this causes an error

    /homqobject.h:314: error: static assertion failed: Signal and slot arguments are not compatible.
    Q_STATIC_ASSERT_X((FunctorArgumentCount >= 0),
    ^

    Does the bind work in combination with signal / slot connection?



  • @gde23 said in Automatically accept choice of QComboBox in a QStyledItemDelegate:

    Does the bind work in combination with signal / slot connection?

    Yes, it's used in Qt itself. Can you show us your connection including the type off all the arguments please?



  • void MyDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
    {
        QComboBox *comboBox = static_cast<QComboBox*>(editor);
        comboBox->setCurrentText(value);
        comboBox->showPopup();
        connect(comboBox,QOverload<int>::of(&QComboBox::currentIndexChanged),
                             this, std::bind(&QStyledItemDelegate::commitData, this, comboBox));                
         return;     
    }
    

    this is of type MyDelegate : public QStyledItemDelegate



  • it's a sneaky constness problem. easy but dirty solution: connect(comboBox,QOverload<int>::of(&QComboBox::currentIndexChanged),this,std::bind(&QStyledItemDelegate::commitData, const_cast<MyDelegate*>(this), comboBox));

    Better designed solution:

    • in MyDelegate add Q_SIGNAL void comboChanged(QWidget*) const.
    • in MyDelegate's constructor add connect(this,&MyDelegate::comboChanged,this,&MyDelegate::commitData);
    • as last line of setEditorData put connect(comboBox,QOverload<int>::of(&QComboBox::currentIndexChanged),this, std::bind(&MyDelegate::comboChanged, this, comboBox));


  • Thanks a lot. Your solutions work perfectly (both of them).

    I've further changed the combeChanegd() signal to a slot that further emits a closeEditor() signal.

    void MyDelegate::comboChanged(QWidget *editor)
    {
        emit commitData(editor);
        emit closeEditor(editor, QAbstractItemDelegate::NoHint);
    }
    

    That way the delegate is directly closed after a selection was made.


Log in to reply