Historic QComboBox with QStringListModel



  • Hi,
    I am trying to create a QComboBox that attaches to a model for listing history items. The main features are items entered in the lineedit area of the combo are added to the history if not present. Selected items and items entered that already appear in the combo are moved to the top. If number of items exceed a number, older items are removed.

    My questions:

    1. Why when entering in setData from model, when I request the string list, there is an empty string on it ?
    2. When pushTopActivated is triggered, how to set as current index the activated item pushed on top ?
    3. Any idea on how to handle Del key to delete the current activated item ?

    Thanks

    histocombodialog.h

    #ifndef HISTOCOMBODIALOG_H
    #define HISTOCOMBODIALOG_H
    
    #include <QDialog>
    #include <QComboBox>
    #include <QGridLayout>
    #include <QStringListModel>
    #include <QStringList>
    
    class ComboModel : public QStringListModel
    {
        Q_OBJECT
    
    public:
        ComboModel(QObject *parent = 0)
            : QStringListModel(parent), mMaxItems(5) {}
        ComboModel(const QStringList &strings, QObject *parent = 0)
            : QStringListModel(strings, parent), mMaxItems(5) {}
    
        bool setData(const QModelIndex &index, const QVariant &value,
                     int role = Qt::EditRole);
    
    private slots:
        void pushTopActivated(int index);
    
    private:
        void pushOutOlder();
    
        int mMaxItems;
    };
    
    class HistoComboDialog : public QDialog
    {
        Q_OBJECT
    
    public:
        HistoComboDialog(QWidget *parent = 0);
        ~HistoComboDialog();
    
        void setupGUI();
    
        QComboBox* combo;
        QGridLayout *gridLayout;
    };
    
    #endif // HISTOCOMBODIALOG_H
    

    histocombodialog.cpp

    #include "histocombodialog.h"
    
    HistoComboDialog::HistoComboDialog(QWidget *parent)
        : QDialog(parent)
    {
        setupGUI();
    
        QStringList list;
        list << "Bill Murray" << "John Doe" << "Bill Clinton";
    
        ComboModel* model = new ComboModel(list);
        combo->setModel(model);
    
        connect(combo, SIGNAL(activated(int)),
                        model, SLOT(pushTopActivated(int)));
    }
    
    HistoComboDialog::~HistoComboDialog()
    {
    }
    
    void HistoComboDialog::setupGUI()
    {
        resize(480, 320);
    
        combo = new QComboBox( this );
        combo->setMinimumSize(QSize(180, 0));
        combo->setInsertPolicy(QComboBox::InsertAtTop);
        combo->setEditable(true);
    
        gridLayout = new QGridLayout();
        gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
    
        gridLayout->addWidget(combo, 0, 0);
    
        setLayout(gridLayout);
    }
    
    bool ComboModel::setData(const QModelIndex &index,
                             const QVariant &value, int role)
    {
        QStringList lst = stringList();
    
        if (index.row() >= 0 && index.row() < lst.size()
            && (role == Qt::EditRole || role == Qt::DisplayRole))
        {
            int i = -1;
            QStringList::iterator it = std::find(lst.begin(), lst.end(), value.toString());
            if (it != lst.end())
                i = it - lst.begin();
    
            if (i != -1) // found
            {
                // move the item to the top of the list
                lst.removeAt(i);
                lst.insert(0, value.toString());
    
                setStringList(lst);
            }
            else // not found, add it
            {
                // add the new item to the top of the list
                lst.insert(0, value.toString());
    
                setStringList(lst);
                pushOutOlder();
            }
    
            dataChanged(index, index);
    
            return true;
        }
    
        return false;
    }
    
    void ComboModel::pushOutOlder()
    {
        // checks the number of items in the list and if it has been exceeded removes extra items
        QStringList lst = stringList();
        if (lst.size() > mMaxItems)
        {
            int count = lst.size() - mMaxItems;
            for (int i(0); i < count; ++i )
                lst.removeLast();
    
            setStringList(lst);
        }
    }
    
    void ComboModel::pushTopActivated(int index)
    {
        // move the selected item tot he top of the list
        if (index > 0)
        {
            emit layoutAboutToBeChanged();
    
            QStringList lst = stringList();
            QString value = lst.at(index);
            lst.removeAt(index);
            lst.insert(0, value);
    
            setStringList(lst);
    
            emit layoutChanged();
        }
    }
    

Log in to reply
 

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