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
Forum Updated to NodeBB v4.3 + New Features

QCompleter custom popup position is not correct

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 4 Posters 1.1k 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