QCompleter in QTableView: show always, even before user input



  • I have a QTableView showing a custom editable model. When editing strings in the view (with the default QLineEdit created by the default delegate) I want to see a suggestion of "known" predefined values for that cell. So I subclassed QStyledItemDelegate and (in createEditor()) added a QCompleter to the QLineEdit.
    This works, when entering text into a cell the popup appears & I can select (with mouse or arrow keys) from the proposals. However, I'd like the popup to appear before entering anything, directly after triggering the edit.

    I tried to call QCompleter::setCompletionPrefix(index.data(Qt::EditRole).toString()) and QCompleter::complete() from QStyledItemDelegate::updateEditorGeometry() and QStyledItemDelegate::setEditorData(), to no avail.


  • Lifetime Qt Champion

    Hi,

    Something like completer->popup()->show(); should do what you want.

    Hope it helps.


  • Moderators

    @azrdev said:

    I tried to call QCompleter::setCompletionPrefix(index.data(Qt::EditRole).toString()) and QCompleter::complete()

    actually this should be the correct way of showing the popup - correctly positioned and with the right completions. I guess the place where you call it is just incorrect.

    Try to do it on the show event by doing the following:

    QWidget* MyItemDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const
    {
            QWidget* editor = QStyledItemDelegate::createEditor(parent, option, index);
            m_Editor = editor; //member to store the current editor. Type is "QPointer<QWidget>"
            if( QLineEdit* lineEdit = qobject_cast<QLineEdit*>(editor) )
            {
                 //set your completer on the lineEdit
            }
            
            return editor;
    }
    
    bool MyItemDelegate::editorEvent(QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index)
    {
          if( QLineEdit* lineEdit = qobject_cast<QLineEdit*>(m_Editor) )
          {
                switch( event->type() )
                {
                     case QEvent::Show:
                     {
                             if( QCompleter* completer = lineEdit->completer() )
                             {
                                       completer->setCompletionPrefix(index.data(Qt::EditRole).toString());
                                      completer->complete();
                             }
                     }
                }
          }
          return QStyledItemDelegate::editorEvent(event, model, option, index);
    }
    

    (untested)



  • @raven-worx said in QCompleter in QTableView: show always, even before user input:

    QWidget* MyItemDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const
    ...
            m_Editor = editor; //member to store the current editor. Type is "QPointer<QWidget>"
    ...
          if( QLineEdit* lineEdit = qobject_cast<QLineEdit*>(m_Editor) )
    

    This does compile, because createEditor() is const, which disallows saving the editor widget in a member. Also, you assume there exists only ever one editor -- don't know if that's true/guaranteed by Qt.


  • Moderators

    @azrdev
    declare the m_Editor variable as mutable.
    If you do not have any special treatment with the editor in a normal view it should work.



  • @raven-worx said in QCompleter in QTableView: show always, even before user input:

    declare the m_Editor variable as mutable.

    This makes it compile (even though I'm not sure about the implications), but it doesn't help me: there is no Show event handled in editorEvent ever (tested with printf-debugging - yes, before the test for QLineEdit), I'm only getting Mouse events.


    @SGaist said in QCompleter in QTableView: show always, even before user input:

    Something like completer->popup()->show(); should do what you want.

    Nope, does not help.


    I figured (using qDebug, again), the place where I should put my popup-opening call is setEditorData. In there, I receive the QLineEdit and it's QCompleter: But I cannot make it show the popup. I tried now:

    completer->setCompletionPrefix(index.data(Qt::EditRole).toString());
    completer->complete();
    completer->popup()->show();
    

    Note: Sometimes the popup is shown for a very short time, but immediately hides. When repeatedly entering & leaving edit mode this only works the first time.



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