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 custom popup position is not correct

QCompleter custom popup position is not correct

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 4 Posters 1.3k Views 2 Watching
  • 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
    Abdurahman_Gulamkadirov
    wrote on last edited by Abdurahman_Gulamkadirov
    #1

    Hi there.

    I'm implementing simple search, there's a line edit. When user inputs something, there should be table popup. QCompleter should search user's input on 2 columns, so I had to create custom line edit. I used QCompleter, QSqlTableModel for searching, QTableView for popup, here's some code:

    void SearchEdit::setSearchTable(QTableView *table, QSqlTableModel *model,
                                    QStringList columns)
    {
        if(m_completer == nullptr)
            delete m_completer;
        m_completer = new QCompleter;
        m_completer->setPopup(table);
        m_completer->setCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive);
        m_completer->setModel(model);erak
        m_model = model;
        m_table = table;
        m_table->horizontalHeader()->setHighlightSections(false);
        connect(m_completer, SIGNAL(activated(QString)),
                this, SLOT(insertCompletionWord(QString)));
        m_table->horizontalHeader()->setStretchLastSection(true);
        m_table->resizeColumnsToContents();
        m_completer->popup()->setMaximumSize(300, 200);
    
        connect(m_completer, SIGNAL(activated(const QModelIndex&)),
                this, SLOT(completerActivated(const QModelIndex&)));
    }
    //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=--=-=-
    void SearchEdit::keyPressEvent(QKeyEvent *e)
    {
        QLineEdit::keyPressEvent(e);
        if(m_completer == nullptr) return;
        showCustomCompleter();
    }
    //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=--=-=-
    void SearchEdit::showCustomCompleter()
    {
        if(this->text().length() < 3)
        {
            m_table->hide();
            return;
        }
        m_model->setFilter(columns.join(tr(" LIKE \"%%1%\" OR ").arg(this->text())) + tr(" LIKE \"%%1%\"").arg(this->text()));
        m_model->select();
        m_completer->complete();
    }
    

    But popup(the QTableView) stays at it's place when window is resized or moved. I couldn't fix it. Could you plz help me?

    SGaistS eyllanescE 2 Replies Last reply
    0
    • A Abdurahman_Gulamkadirov

      Hi there.

      I'm implementing simple search, there's a line edit. When user inputs something, there should be table popup. QCompleter should search user's input on 2 columns, so I had to create custom line edit. I used QCompleter, QSqlTableModel for searching, QTableView for popup, here's some code:

      void SearchEdit::setSearchTable(QTableView *table, QSqlTableModel *model,
                                      QStringList columns)
      {
          if(m_completer == nullptr)
              delete m_completer;
          m_completer = new QCompleter;
          m_completer->setPopup(table);
          m_completer->setCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive);
          m_completer->setModel(model);erak
          m_model = model;
          m_table = table;
          m_table->horizontalHeader()->setHighlightSections(false);
          connect(m_completer, SIGNAL(activated(QString)),
                  this, SLOT(insertCompletionWord(QString)));
          m_table->horizontalHeader()->setStretchLastSection(true);
          m_table->resizeColumnsToContents();
          m_completer->popup()->setMaximumSize(300, 200);
      
          connect(m_completer, SIGNAL(activated(const QModelIndex&)),
                  this, SLOT(completerActivated(const QModelIndex&)));
      }
      //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=--=-=-
      void SearchEdit::keyPressEvent(QKeyEvent *e)
      {
          QLineEdit::keyPressEvent(e);
          if(m_completer == nullptr) return;
          showCustomCompleter();
      }
      //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=--=-=-
      void SearchEdit::showCustomCompleter()
      {
          if(this->text().length() < 3)
          {
              m_table->hide();
              return;
          }
          m_model->setFilter(columns.join(tr(" LIKE \"%%1%\" OR ").arg(this->text())) + tr(" LIKE \"%%1%\"").arg(this->text()));
          m_model->select();
          m_completer->complete();
      }
      

      But popup(the QTableView) stays at it's place when window is resized or moved. I couldn't fix it. Could you plz help me?

      eyllanescE Offline
      eyllanescE Offline
      eyllanesc
      wrote on last edited by eyllanesc
      #9

      @Abdurahman_Gulamkadirov I don't see the need to launch QCompleter manually, it is enough to override the splitPath method:

      filtercompleter.h

      #ifndef FILTERCOMPLETER_H
      #define FILTERCOMPLETER_H
      
      #include <QCompleter>
      
      class FilterCompleter: public QCompleter
      {
      public:
          FilterCompleter(const QStringList & columns, QAbstractItemModel *model, QObject *parent = nullptr);
          QStringList splitPath(const QString &path) const;
      private:
          QStringList m_columns;
      };
      
      #endif // FILTERCOMPLETER_H
      

      filtercompleter.cpp

      #include "filtercompleter.h"
      
      #include <QAbstractItemModel>
      #include <QTableView>
      #include <QSqlTableModel>
      #include <QHeaderView>
      
      #include <QDebug>
      
      FilterCompleter::FilterCompleter(const QStringList &columns, QAbstractItemModel *model, QObject *parent)
          : QCompleter(model, parent), m_columns(columns)
      {
          setCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive);
          QTableView *view = new QTableView;
          setPopup(view);
          view->horizontalHeader()->setHighlightSections(false);
          view->horizontalHeader()->setStretchLastSection(true);
          view->resizeColumnsToContents();
          popup()->setMaximumSize(300, 200);
      }
      
      QStringList FilterCompleter::splitPath(const QString &path) const
      {
          if(QSqlTableModel *sqlmodel = qobject_cast<QSqlTableModel *>(model())){
              QString filter = m_columns.join(tr(" LIKE \"%%1%\" OR ").arg(path)) + tr(" LIKE \"%%1%\"").arg(path);
              qDebug() << filter;
              sqlmodel->setFilter(filter);
          }
          return QCompleter::splitPath(path);
      }
      

      Example:

      QLineEdit lineedit;
      FilterCompleter *completer = new FilterCompleter({"COL1", "COL2"}, model);
      lineedit.setCompleter(completer);
      

      If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

      A 1 Reply Last reply
      3
      • mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by
        #2

        Hi
        Try set parent to the completer
        m_completer = new QCompleter(table);

        A 1 Reply Last reply
        0
        • mrjjM mrjj

          Hi
          Try set parent to the completer
          m_completer = new QCompleter(table);

          A Offline
          A Offline
          Abdurahman_Gulamkadirov
          wrote on last edited by
          #3

          @mrjj Unfortunately it didn't work

          1 Reply Last reply
          0
          • A Abdurahman_Gulamkadirov

            Hi there.

            I'm implementing simple search, there's a line edit. When user inputs something, there should be table popup. QCompleter should search user's input on 2 columns, so I had to create custom line edit. I used QCompleter, QSqlTableModel for searching, QTableView for popup, here's some code:

            void SearchEdit::setSearchTable(QTableView *table, QSqlTableModel *model,
                                            QStringList columns)
            {
                if(m_completer == nullptr)
                    delete m_completer;
                m_completer = new QCompleter;
                m_completer->setPopup(table);
                m_completer->setCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive);
                m_completer->setModel(model);erak
                m_model = model;
                m_table = table;
                m_table->horizontalHeader()->setHighlightSections(false);
                connect(m_completer, SIGNAL(activated(QString)),
                        this, SLOT(insertCompletionWord(QString)));
                m_table->horizontalHeader()->setStretchLastSection(true);
                m_table->resizeColumnsToContents();
                m_completer->popup()->setMaximumSize(300, 200);
            
                connect(m_completer, SIGNAL(activated(const QModelIndex&)),
                        this, SLOT(completerActivated(const QModelIndex&)));
            }
            //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=--=-=-
            void SearchEdit::keyPressEvent(QKeyEvent *e)
            {
                QLineEdit::keyPressEvent(e);
                if(m_completer == nullptr) return;
                showCustomCompleter();
            }
            //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=--=-=-
            void SearchEdit::showCustomCompleter()
            {
                if(this->text().length() < 3)
                {
                    m_table->hide();
                    return;
                }
                m_model->setFilter(columns.join(tr(" LIKE \"%%1%\" OR ").arg(this->text())) + tr(" LIKE \"%%1%\"").arg(this->text()));
                m_model->select();
                m_completer->complete();
            }
            

            But popup(the QTableView) stays at it's place when window is resized or moved. I couldn't fix it. Could you plz help me?

            SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #4

            Hi,

            @Abdurahman_Gulamkadirov said in QCompleter custom popup position is not correct:

            if(m_completer == nullptr)
            delete m_completer;

            There's no need to delete a pointer that is already null.

            Shouldn't you pass this as parent of your completer ?

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

            A 1 Reply Last reply
            1
            • SGaistS SGaist

              Hi,

              @Abdurahman_Gulamkadirov said in QCompleter custom popup position is not correct:

              if(m_completer == nullptr)
              delete m_completer;

              There's no need to delete a pointer that is already null.

              Shouldn't you pass this as parent of your completer ?

              A Offline
              A Offline
              Abdurahman_Gulamkadirov
              wrote on last edited by Abdurahman_Gulamkadirov
              #5

              @SGaist Yes you're right. I had to change m_completer != nullptr, but now that is not a main problem.

              I had done:
              8b0487bf-4ea8-42ff-824a-4b8fdda4b311-image.png

              When I start my program and use search edit, it's working normal:
              df9d6d58-80fd-41e8-9e92-b536eb472ca9-image.png

              But when I move the window:
              02632e54-e836-4d24-83b6-2e1fc1ead28f-image.png

              I think I should hide completer popup when the mainwindow is resized/moved, but IDK how to do.

              P.S: I'm not able to load gif.

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

                Why are you triggering the popup manually ?

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

                A 1 Reply Last reply
                0
                • SGaistS SGaist

                  Why are you triggering the popup manually ?

                  A Offline
                  A Offline
                  Abdurahman_Gulamkadirov
                  wrote on last edited by Abdurahman_Gulamkadirov
                  #7

                  @SGaist if I use setCompleter(QCompleter*), then my completer can only search on only one column. I want to search 2 columns, that's why I'm not using completer directly.

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

                    Why do you need two columns ?

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

                    A 1 Reply Last reply
                    0
                    • A Abdurahman_Gulamkadirov

                      Hi there.

                      I'm implementing simple search, there's a line edit. When user inputs something, there should be table popup. QCompleter should search user's input on 2 columns, so I had to create custom line edit. I used QCompleter, QSqlTableModel for searching, QTableView for popup, here's some code:

                      void SearchEdit::setSearchTable(QTableView *table, QSqlTableModel *model,
                                                      QStringList columns)
                      {
                          if(m_completer == nullptr)
                              delete m_completer;
                          m_completer = new QCompleter;
                          m_completer->setPopup(table);
                          m_completer->setCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive);
                          m_completer->setModel(model);erak
                          m_model = model;
                          m_table = table;
                          m_table->horizontalHeader()->setHighlightSections(false);
                          connect(m_completer, SIGNAL(activated(QString)),
                                  this, SLOT(insertCompletionWord(QString)));
                          m_table->horizontalHeader()->setStretchLastSection(true);
                          m_table->resizeColumnsToContents();
                          m_completer->popup()->setMaximumSize(300, 200);
                      
                          connect(m_completer, SIGNAL(activated(const QModelIndex&)),
                                  this, SLOT(completerActivated(const QModelIndex&)));
                      }
                      //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=--=-=-
                      void SearchEdit::keyPressEvent(QKeyEvent *e)
                      {
                          QLineEdit::keyPressEvent(e);
                          if(m_completer == nullptr) return;
                          showCustomCompleter();
                      }
                      //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=--=-=-
                      void SearchEdit::showCustomCompleter()
                      {
                          if(this->text().length() < 3)
                          {
                              m_table->hide();
                              return;
                          }
                          m_model->setFilter(columns.join(tr(" LIKE \"%%1%\" OR ").arg(this->text())) + tr(" LIKE \"%%1%\"").arg(this->text()));
                          m_model->select();
                          m_completer->complete();
                      }
                      

                      But popup(the QTableView) stays at it's place when window is resized or moved. I couldn't fix it. Could you plz help me?

                      eyllanescE Offline
                      eyllanescE Offline
                      eyllanesc
                      wrote on last edited by eyllanesc
                      #9

                      @Abdurahman_Gulamkadirov I don't see the need to launch QCompleter manually, it is enough to override the splitPath method:

                      filtercompleter.h

                      #ifndef FILTERCOMPLETER_H
                      #define FILTERCOMPLETER_H
                      
                      #include <QCompleter>
                      
                      class FilterCompleter: public QCompleter
                      {
                      public:
                          FilterCompleter(const QStringList & columns, QAbstractItemModel *model, QObject *parent = nullptr);
                          QStringList splitPath(const QString &path) const;
                      private:
                          QStringList m_columns;
                      };
                      
                      #endif // FILTERCOMPLETER_H
                      

                      filtercompleter.cpp

                      #include "filtercompleter.h"
                      
                      #include <QAbstractItemModel>
                      #include <QTableView>
                      #include <QSqlTableModel>
                      #include <QHeaderView>
                      
                      #include <QDebug>
                      
                      FilterCompleter::FilterCompleter(const QStringList &columns, QAbstractItemModel *model, QObject *parent)
                          : QCompleter(model, parent), m_columns(columns)
                      {
                          setCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive);
                          QTableView *view = new QTableView;
                          setPopup(view);
                          view->horizontalHeader()->setHighlightSections(false);
                          view->horizontalHeader()->setStretchLastSection(true);
                          view->resizeColumnsToContents();
                          popup()->setMaximumSize(300, 200);
                      }
                      
                      QStringList FilterCompleter::splitPath(const QString &path) const
                      {
                          if(QSqlTableModel *sqlmodel = qobject_cast<QSqlTableModel *>(model())){
                              QString filter = m_columns.join(tr(" LIKE \"%%1%\" OR ").arg(path)) + tr(" LIKE \"%%1%\"").arg(path);
                              qDebug() << filter;
                              sqlmodel->setFilter(filter);
                          }
                          return QCompleter::splitPath(path);
                      }
                      

                      Example:

                      QLineEdit lineedit;
                      FilterCompleter *completer = new FilterCompleter({"COL1", "COL2"}, model);
                      lineedit.setCompleter(completer);
                      

                      If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

                      A 1 Reply Last reply
                      3
                      • SGaistS SGaist

                        Why do you need two columns ?

                        A Offline
                        A Offline
                        Abdurahman_Gulamkadirov
                        wrote on last edited by
                        #10

                        @SGaist I'm making simple search edit, it should search product by name or by barcode

                        1 Reply Last reply
                        0
                        • eyllanescE eyllanesc

                          @Abdurahman_Gulamkadirov I don't see the need to launch QCompleter manually, it is enough to override the splitPath method:

                          filtercompleter.h

                          #ifndef FILTERCOMPLETER_H
                          #define FILTERCOMPLETER_H
                          
                          #include <QCompleter>
                          
                          class FilterCompleter: public QCompleter
                          {
                          public:
                              FilterCompleter(const QStringList & columns, QAbstractItemModel *model, QObject *parent = nullptr);
                              QStringList splitPath(const QString &path) const;
                          private:
                              QStringList m_columns;
                          };
                          
                          #endif // FILTERCOMPLETER_H
                          

                          filtercompleter.cpp

                          #include "filtercompleter.h"
                          
                          #include <QAbstractItemModel>
                          #include <QTableView>
                          #include <QSqlTableModel>
                          #include <QHeaderView>
                          
                          #include <QDebug>
                          
                          FilterCompleter::FilterCompleter(const QStringList &columns, QAbstractItemModel *model, QObject *parent)
                              : QCompleter(model, parent), m_columns(columns)
                          {
                              setCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive);
                              QTableView *view = new QTableView;
                              setPopup(view);
                              view->horizontalHeader()->setHighlightSections(false);
                              view->horizontalHeader()->setStretchLastSection(true);
                              view->resizeColumnsToContents();
                              popup()->setMaximumSize(300, 200);
                          }
                          
                          QStringList FilterCompleter::splitPath(const QString &path) const
                          {
                              if(QSqlTableModel *sqlmodel = qobject_cast<QSqlTableModel *>(model())){
                                  QString filter = m_columns.join(tr(" LIKE \"%%1%\" OR ").arg(path)) + tr(" LIKE \"%%1%\"").arg(path);
                                  qDebug() << filter;
                                  sqlmodel->setFilter(filter);
                              }
                              return QCompleter::splitPath(path);
                          }
                          

                          Example:

                          QLineEdit lineedit;
                          FilterCompleter *completer = new FilterCompleter({"COL1", "COL2"}, model);
                          lineedit.setCompleter(completer);
                          
                          A Offline
                          A Offline
                          Abdurahman_Gulamkadirov
                          wrote on last edited by
                          #11

                          @eyllanesc Thank you a lot! It's really simple than I thought, you saved me from doing extra works

                          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