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:
- Why when entering in setData from model, when I request the string list, there is an empty string on it ?
- When pushTopActivated is triggered, how to set as current index the activated item pushed on top ?
- 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(); } }