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

QItemDelegate: commit QComboBox value to model on click



  • I am setting a QStyledItemDelegate on my model for a particular field, and returning a QComboBox from QStyledItemDelegate::createEditor

    QComboBox* createEditor(QWidget* parent)
    {
        QComboBox* cb = new QComboBox(parent);
    
        cb->addItem("UNDEFINED");
        cb->addItem("TEST");
        cb->addItem("OSE");
        cb->addItem("TSE");
    
        return cb;
    }
    
    void setEditorData(QWidget* editor, const QModelIndex& index)
    {
        QComboBox* cb = qobject_cast<QComboBox*>(editor);
        if (!cb)
            throw std::logic_error("editor is not a combo box");
    
        QString value = index.data(Qt::EditRole).toString();
        int idx = cb->findText(value);
        if (idx >= 0)
            cb->setCurrentIndex(idx);
    
        cb->showPopup();
    }
    

    This is working fine, and when I select the field in question I am shown a combo box.

    combobox open

    When I select an option from the drop-down list, the combobox closes and the item is displayed with a drop-down icon next to it:

    selected

    At this point I would like the QStyledItemDelegate::setModelData function to be called, so that selecting an item in the list commits the data to the model.

    However, I am required to first press Enter to commit the data (whereby the drop-down icon disappears)

    committed

    Only after I press Enter does my QStyledItemDelegate::setModelData function get called.

    void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index)
    {
    	QComboBox* cb = qobject_cast<QComboBox*>(editor);
    	if (!cb)
    		throw std::logic_error("editor is not a combo box");
    
    	model->setData(index, cb->currentText(), Qt::EditRole);
    }
    

    Question:

    How can I configure my QComboBox so automatically commit the data when the user selects an item in the list, and the combobox list closes?


  • Lifetime Qt Champion

    Hi,

    How do you know the model data is not set correctly ?

    Did you re-implement setModelData in your QItemDelegate ?

    By the way, why not use QStyledItemDelegate ?



  • @SGaist I have updated the question to show setModelData is correctly called, it's just that it only gets called after I press enter, whereas I would like the selection of an item in the list (which causes the drop-down list to close) to call setModelData.

    I'm trying to overcome the 2-step process required to get setModelData to be called:

    • First the user has to either click the mouse to select the item in the list of available items, or using the keypad, select an item and then press enter. This closes the drop-down list, but still shows the drop-down indicator on the right-side of the combobox. (setModelData has not been called at this point.) See 2nd image I posted above
    • Second the user has to press Enter to "commit" the value to the model. This causes the drop-down indicator on the right-side of the combobox to disappear, and only now does setModelData get called. See 3rd image I posted above

    Re QStyledItemDelegate I am actually using that, I just has already started typing QItemDelegate and didn't think it important to the question to go back and change them. I've done that now.



  • before cb->showPopup(); add connect(cb,QOverload<int>::of(&QComboBox::currentIndexChanged),this,std::bind(&QStyledItemDelegate::commitData,this,cb));


  • Lifetime Qt Champion

    For the class type, it was just curiosity.

    And for the rest, do as @VRonin suggests, I was about to propose a similar solution.



  • Thanks @VRonin and @SGaist , that works perfectly!


Log in to reply