Search code examples
c++qtqt4

A QLineEdit with a QCompleter won't show the QCompleter's popup menu with an empty text field


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?


Solution

  • 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:

    • define textChanged slot for your lineedit;
    • override customEvent method for your window;
    • in the textChanged slot send user event to the window whenever lineedit's text has zero length;
    • in the customEvent method show completer whenever user event is received;

    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