qtpyqtqcombobox

remove items from QComboBox from ui


I am trying to tweak the ui of a QComboBox in a way that the user can remove items from the drop down list (without first selecting them).

The background is that I am using the QComboBox to indicate which data file is open right now. I am also using it as a cache for recently opened files. I would like the user to be able to remove entries he does not want to have listed anymore. This could be either by just hitting the delete key, or a context menu, or whatever is straightforward to implement. I do not want to rely on selecting the item first. A similar behavior can be found in Firefox, where old cached suggestions for an entry filed can be deleted.

I was considering subclassing the list view used by QComboBox, however, I did not find enough documentation to get me started.

I would be grateful for any hints and suggestions. I am using PyQt, but have no problems with C++ samples.


Solution

  • I solved this problem using code from the installEventFilter documentation.

    //must be in a header, otherwise moc gets confused with missing vtable
    class DeleteHighlightedItemWhenShiftDelPressedEventFilter : public QObject
    {
         Q_OBJECT
    protected:
        bool eventFilter(QObject *obj, QEvent *event);
    };
    
    bool DeleteHighlightedItemWhenShiftDelPressedEventFilter::eventFilter(QObject *obj, QEvent *event)
    {
        if (event->type() == QEvent::KeyPress)
        {
            QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
            if (keyEvent->key() == Qt::Key::Key_Delete && keyEvent->modifiers() == Qt::ShiftModifier)
            {
                auto combobox = dynamic_cast<QComboBox *>(obj);
                if (combobox){
                    combobox->removeItem(combobox->currentIndex());
                    return true;
                }
            }
        }
        // standard event processing
        return QObject::eventFilter(obj, event);
    }
    
    myQComboBox->installEventFilter(new DeleteHighlightedItemWhenShiftDelPressedEventFilter);