QCompleter custom popup position is not correct
-
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?
-
@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);
-
Hi
Try set parent to the completer
m_completer = new QCompleter(table); -
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 ?
-
@SGaist Yes you're right. I had to change m_completer != nullptr, but now that is not a main problem.
I had done:
When I start my program and use search edit, it's working normal:
But when I move the window:
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.
-
Why are you triggering the popup manually ?
-
Why do you need two columns ?
-
@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);
-
@eyllanesc Thank you a lot! It's really simple than I thought, you saved me from doing extra works