[SOLVED] search/filter inside Combobox QCombobox



  • Hi,
    I'm using a Qcombobox and I'm trying to implement a search/filter on it.
    as model I'm using a SqlQuerryModel.

    E.g. List items:
    Albert Einstand
    Andrew Robert
    Paul Manson
    Michael Jordan

    ok now in in the combobox I'll start typing
    "a" - I get the hole list
    "an"- =>
    Albert Einstand
    Andrew Robert
    Paul Manson
    "and"- =>
    Albert Einstand
    Andrew Robert
    "andr"- => Andrew Robert
    please note that my desire is that the refresh of the list to be done automatically without any update button pressed. on_combobox_currentTextChanged event.
    also the list have to remain open as the user is typing and else to work like a combobox with this new features


  • Lifetime Qt Champion

    Hi,

    Maybe "this":http://qt-project.org/doc/qt-5/qcompleter.html will do

    Hope it helps



  • yep i've done this

    @QCompleter *mycompletear = new QCompleter(this);
    mycompletear->setCaseSensitivity(Qt::CaseInsensitive);
    mycompletear->setModel(proxyModel);
    mycompletear->setCompletionColumn(1);
    mycompletear->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
    ui->comp_comb->setCompleter(mycompletear);@

    but unfortunately is showing an empty combobox if i type nothing in it


  • Lifetime Qt Champion

    What should it show ?



  • so.. when the form load and the user click on dropdown (combobox button) it have to show the full list f about 50 items (but only 6 or 8 with a scroolbar on the right ) and when the user start typing something then the list have to change accordingly.
    but now when the user click is showing an empty list and if is starting to type something for example just an "a" it will already complete the first item - when it have to show only the items and the user to be able to select it from the list


  • Lifetime Qt Champion

    Do you use the same model for both the combo box and the completer ?



  • yes I use the same proxy models... is here the trick? to use different models? I'll try this and I will let you know the result I also have a model and a proxymodel. i'll see the difference and let you know. thanks for this



  • Voila the "solution" hope will help other in the future. a very nice future for a combo to to have it.
    this is the cpp file
    @
    model = new QSqlQueryModel;
    model->setQuery("SELECT * FROM company_tbl");

    proxyModel = new QSortFilterProxyModel(this);
    proxyModel->setSourceModel(model);
    proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
    proxyModel->setFilterKeyColumn(1);

    proxyModel1 = new QSortFilterProxyModel(this);
    proxyModel1->setSourceModel(model);
    proxyModel1->setFilterCaseSensitivity(Qt::CaseInsensitive);
    proxyModel1->setFilterKeyColumn(1);

    ui->comp_comb->setModel(proxyModel1);
    ui->comp_comb->setModelColumn(1);

    QCompleter *mycompletear = new QCompleter(this);
    mycompletear->setCaseSensitivity(Qt::CaseInsensitive);
    mycompletear->setModel(proxyModel);
    mycompletear->setCompletionColumn(1);
    mycompletear->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
    ui->comp_comb->setCompleter(mycompletear);

    @

    and also this is the

    @void MainWindow::on_comp_comb_currentTextChanged(const QString &arg1) {
    if (!arg1.isEmpty()) {
    proxyModel->setFilterFixedString(arg1);
    //the following line will do an empty combobox - this is not a fix.. but a temporary thing just to work we will have just the compleater filtered
    //proxyModel1->setFilterFixedString(arg1);
    }
    qDebug() << arg1;
    }@

    and this is the h file under private:
    @
    private:
    QSqlQueryModel *model;
    QSortFilterProxyModel *proxyModel;
    QSortFilterProxyModel *proxyModel1;@

    hope this will help others that need to filter a combobox after any letter from the word
    Have a good day...
    PS - if you have a better one please share it with me...
    Many thanks



  • I have a QTableView with a QSqlRelationalTableModel.
    I obtained model editing with search/filter support this way:

    class PrettyComboBox : public QSqlRelationalDelegate
    {
    public:
      explicit PrettyComboBox(QObject *parent = nullptr);
    
      QWidget* createEditor(  QWidget *parent, const QStyleOptionViewItem &option
                            , const QModelIndex &index) const override;
    };
    
    PrettyComboBox::PrettyComboBox(QObject *parent)
      : QSqlRelationalDelegate{parent} {}
    
    
    QWidget* PrettyComboBox::createEditor(  QWidget *parent
                                          , const QStyleOptionViewItem &option
                                          , const QModelIndex &index) const
    {
      auto w = QSqlRelationalDelegate::createEditor(parent, option, index);
    
      if (auto c = dynamic_cast<QComboBox*>(w)) {
    
        c->setEditable(true);
        c->setInsertPolicy(QComboBox::NoInsert);
    
        auto proxy = new QSortFilterProxyModel(w);
        proxy->setSourceModel(c->model());
        proxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
        proxy->setFilterKeyColumn(c->modelColumn());
    
        auto completer = new QCompleter(w);
        completer->setCaseSensitivity(Qt::CaseInsensitive);
        completer->setModel(proxy);
        completer->setCompletionColumn(c->modelColumn());
        completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
        c->setCompleter(completer);
    
        connect(  c, &QComboBox::editTextChanged
                , [proxy](const QString &txt) {
                    proxy->setFilterFixedString(txt); });
      }
    
      return w;
    }
    
    ...and somewhere
    table_view->setItemDelegate(new PrettyComboBox(table_view));

Log in to reply
 

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