I have a QLineEdit
, with a QCompleter
object associated to it. If the user enters at least one character, the popup menu from the QCompleter
is shown, but when the user deletes the last character (thus leaving the field empty) the popup disappears. Is there any way to make it show even when the QLineEdit
's text is empty?
you should be able to force completer's popup window to get shown once your line edit text is erased by using QCompleter::complete slot:
lineEdit->completer()->complete();
Here's how you can do it:
Below is an example:
mainwindow.h:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
protected:
void customEvent(QEvent * event);
private:
Ui::MainWindow *ui;
private slots:
void on_lineEdit_textChanged(QString );
};
mainwindow.cpp:
class CompleteEvent : public QEvent
{
public:
CompleteEvent(QLineEdit *lineEdit) : QEvent(QEvent::User), m_lineEdit(lineEdit) { }
void complete()
{
m_lineEdit->completer()->complete();
}
private:
QLineEdit *m_lineEdit;
};
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QStringList wordList;
wordList << "one" << "two" << "three" << "four";
QLineEdit *lineEdit = new QLineEdit(this);
lineEdit->setGeometry(20, 20, 200, 30);
connect(lineEdit, SIGNAL(textChanged(QString)), SLOT(on_lineEdit_textChanged(QString )));
QCompleter *completer = new QCompleter(wordList, this);
completer->setCaseSensitivity(Qt::CaseInsensitive);
completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
lineEdit->setCompleter(completer);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::customEvent(QEvent * event)
{
QMainWindow::customEvent(event);
if (event->type()==QEvent::User)
((CompleteEvent*)event)->complete();
}
void MainWindow::on_lineEdit_textChanged(QString text)
{
if (text.length()==0)
QApplication::postEvent(this, new CompleteEvent((QLineEdit*)sender()));
}
hope this helps, regards
Here is my solution based on serge_gubenko's answer. This class uses QStringListModel, but it can be easily replaced with any other model.
Completer_line_edit.h
#include <QLineEdit>
#include <QStringListModel>
#include <QTimer>
/*! Line edit widget with auto completion based on QStringListModel.
Modified behaviour: completion list will appear even when contents of
line edit is empty. Full list of options will be showed when line edit
has focus and is empty.
*/
class Completer_line_edit : public QLineEdit {
Q_OBJECT
public:
explicit Completer_line_edit(QWidget *parent = 0);
//! Set list of options used for copmletion.
inline void set_list(QStringList list) { model.setStringList(list); }
private:
QStringListModel model;
void focusInEvent(QFocusEvent *e);
void customEvent(QEvent* e);
QTimer timer;
private slots:
void slot_text_edited();
void slot_call_popup();
};
Completer_line_edit.cpp
#include "Completer_line_edit.h"
#include <QCompleter>
#include <QEvent>
#include <QApplication>
Completer_line_edit::Completer_line_edit(QWidget *parent) :
QLineEdit(parent)
{
setCompleter(new QCompleter());
completer()->setModel(&model);
completer()->setCompletionMode(QCompleter::PopupCompletion);
completer()->setCaseSensitivity(Qt::CaseInsensitive);
connect(this, SIGNAL(textEdited(QString)), this, SLOT(slot_text_edited()));
}
void Completer_line_edit::focusInEvent(QFocusEvent *e) {
QLineEdit::focusInEvent(e);
// force completion when line edit is focued in
completer()->complete();
}
void Completer_line_edit::slot_text_edited() {
qDebug() << "text edited";
// force to show all items when text is empty
completer()->setCompletionMode(text().isEmpty()? QCompleter::UnfilteredPopupCompletion: QCompleter::PopupCompletion);
if (text().isEmpty()) {
// completion list will be hidden now; we will show it again after a delay
timer.singleShot(100, this, SLOT(slot_call_popup()));
}
}
void Completer_line_edit::slot_call_popup() {
// apparently, complete() works only in event handler
QApplication::postEvent(this, new QEvent(QEvent::User));
}
void Completer_line_edit::customEvent(QEvent *e) {
QLineEdit::customEvent(e);
// force completion after text is deleted
completer()->complete();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With