Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QCompleter in QTableView: show always, even before user input
QtWS25 Last Chance

QCompleter in QTableView: show always, even before user input

Scheduled Pinned Locked Moved General and Desktop
completioncompleterviewtableviewc++
6 Posts 3 Posters 5.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    azrdev
    wrote on last edited by
    #1

    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.

    raven-worxR 1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

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

      Hope it helps.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • A azrdev

        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.

        raven-worxR Offline
        raven-worxR Offline
        raven-worx
        Moderators
        wrote on last edited by
        #3

        @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)

        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
        If you have a question please use the forum so others can benefit from the solution in the future

        A 1 Reply Last reply
        0
        • raven-worxR raven-worx

          @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)

          A Offline
          A Offline
          azrdev
          wrote on last edited by
          #4

          @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.

          raven-worxR 1 Reply Last reply
          0
          • A azrdev

            @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.

            raven-worxR Offline
            raven-worxR Offline
            raven-worx
            Moderators
            wrote on last edited by
            #5

            @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.

            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
            If you have a question please use the forum so others can benefit from the solution in the future

            A 1 Reply Last reply
            0
            • raven-worxR raven-worx

              @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.

              A Offline
              A Offline
              azrdev
              wrote on last edited by
              #6

              @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.

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved