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. Struggling with completer example
QtWS25 Last Chance

Struggling with completer example

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 3 Posters 1.3k 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.
  • SikarjanS Offline
    SikarjanS Offline
    Sikarjan
    wrote on last edited by
    #1

    HI,

    I am currently struggling to understand the completer example. What I do not understand is how the function modelFromFile() works. A txt file is read and the content is put in a QStandardItemModel

    QStandardItemModel *m = new QStandardItemModel(words.count(), 2, completer);
    for (int i = 0; i < words.count(); ++i) {
            QModelIndex countryIdx = m->index(i, 0);
            QModelIndex symbolIdx = m->index(i, 1);
            QString country = words[i].mid(0, words[i].length() - 2).trimmed();
            QString symbol = words[i].right(2);
            m->setData(countryIdx, country);
            m->setData(symbolIdx, symbol);
     }
    
    return m;
    

    So the country name is put in row one in the 2D matrix and the country short cut in row two. But nowhere in the rest of the code the completer is told to use row one and not row two. What if I wanted to use row two for completion? Or in my case I would like to show some extra information on the completion. In the example here I would like to display in light grey the country short cut at the end of the completer box and it should not be inserted.
    To get the data displayed I probably need a custom delegate, which I can set by completer->setPopup() but I do not get from the example how the completer knows which data to use.

    Thanks for all suggestions.

    S 1 Reply Last reply
    0
    • SikarjanS Sikarjan

      HI,

      I am currently struggling to understand the completer example. What I do not understand is how the function modelFromFile() works. A txt file is read and the content is put in a QStandardItemModel

      QStandardItemModel *m = new QStandardItemModel(words.count(), 2, completer);
      for (int i = 0; i < words.count(); ++i) {
              QModelIndex countryIdx = m->index(i, 0);
              QModelIndex symbolIdx = m->index(i, 1);
              QString country = words[i].mid(0, words[i].length() - 2).trimmed();
              QString symbol = words[i].right(2);
              m->setData(countryIdx, country);
              m->setData(symbolIdx, symbol);
       }
      
      return m;
      

      So the country name is put in row one in the 2D matrix and the country short cut in row two. But nowhere in the rest of the code the completer is told to use row one and not row two. What if I wanted to use row two for completion? Or in my case I would like to show some extra information on the completion. In the example here I would like to display in light grey the country short cut at the end of the completer box and it should not be inserted.
      To get the data displayed I probably need a custom delegate, which I can set by completer->setPopup() but I do not get from the example how the completer knows which data to use.

      Thanks for all suggestions.

      S Offline
      S Offline
      samdol
      wrote on last edited by
      #2

      @Sikarjan
      First of all, I guess you mean column one/ column two instead of row one/row two.
      http://doc.qt.io/qt-5/qcompleter.html says,
      To set the model on which QCompleter should operate, call setModel(). By default, QCompleter will attempt to match the completion prefix (i.e., the word that the user has started typing) against the Qt::EditRole data stored in column 0 in the model case sensitively. This can be changed using setCompletionRole(), setCompletionColumn(), and setCaseSensitivity().

      So by default the column 0 is the column for completion and if you want to use column two for completion, you can change by setCompletionColumn().

      1 Reply Last reply
      3
      • SikarjanS Offline
        SikarjanS Offline
        Sikarjan
        wrote on last edited by
        #3

        @samdol
        Thanks for pointing that out. Don't know why I did not see that.

        Unfortunately this does not help me creating the completer I want. I managed to have a custom delegate:

        #ifndef COMPLETERDELEGATE_H
        #define COMPLETERDELEGATE_H
        
        #include <QObject>
        #include <QApplication>
        #include <QStyledItemDelegate>
        #include <QPainter>
        #include <QStyle>
        #include <QTextDocument>
        #include <QAbstractTextDocumentLayout>
        #include <QStyleOption>
        
        class CompleterDelegate : public QStyledItemDelegate
        {
        public:
            CompleterDelegate();
        
        protected:
            void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
            QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const;
        };
        
        #endif // COMPLETERDELEGATE_H
        
        #include "completerdelegate.h"
        
        CompleterDelegate::CompleterDelegate()
        {
        
        }
        
        void CompleterDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
        {
            QStyleOptionViewItemV4 optionV4 = option;
            initStyleOption(&optionV4, index);
        
            QStyle *style = optionV4.widget? optionV4.widget->style() : QApplication::style();
        
            QTextDocument doc;
            doc.setHtml(optionV4.text);
        
            // Painting item without text
            optionV4.text = QString();
            style->drawControl(QStyle::CE_ItemViewItem, &optionV4, painter);
        
            QAbstractTextDocumentLayout::PaintContext ctx;
        
            // Highlighting text if item is selected
            if (optionV4.state & QStyle::State_Selected)
                ctx.palette.setColor(QPalette::Text, optionV4.palette.color(QPalette::Active, QPalette::HighlightedText));
        
            QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &optionV4);
            painter->save();
            painter->translate(textRect.topLeft());
            painter->setClipRect(textRect.translated(-textRect.topLeft()));
            doc.documentLayout()->draw(painter, ctx);
            painter->restore();
        }
        
        QSize CompleterDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
        {
            QStyleOptionViewItemV4 optionV4 = option;
            initStyleOption(&optionV4, index);
        
            QTextDocument doc;
            doc.setHtml(optionV4.text);
            doc.setTextWidth(optionV4.rect.width());
            return QSize(doc.idealWidth(), doc.size().height());
        }
        

        And I set the delegate like this

            cDeligate = new CompleterDelegate;
            completer = new QCompleter(compList, this);
            completer->popup()->setItemDelegate(cDeligate);
        

        So how could I access the data from my models second column?

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Hi,

          You can use QModelIndex::sibling.

          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
          • SikarjanS Offline
            SikarjanS Offline
            Sikarjan
            wrote on last edited by
            #5

            @SGaist Thanks again for helping me out.

            In CompleterDelegate I added:

            QStyleOptionViewItem hint = option;
            initStyleOption(&hint, index.sibling(index.row(),1));
            

            Which gave me

            hint.text
            

            to access the content of the second column.

            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