Amol Borkar
Amol Borkar

Reputation: 2599

Why QLineEdit with QCompleter for auto completion doesn't shows up?

I have two QLineEdits in the program being lineEdit and fileName_Edit. lineEdit holds path to a directory (taken from user). Then user enters the name of file in the fileName_Edit. I want to show suggestions to user when he is entering the file name in fileName_Edit. I tried to implement QCompleter like this:
(dirContents is a QStringList which holds the contents of the directory specified by user in lineEdit)

void MainWindow::on_lineEdit_textChanged(const QString &arg1)
{
    QCompleter *fileEditCompleter = new QCompleter(dirContents, this);
    fileEditCompleter->setCaseSensitivity(Qt::CaseInsensitive);
    fileEditCompleter->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
    ui->fileName_Edit->setCompleter(fileEditCompleter);
}

Program compiles successfully but, the completer doesn't shows up. Even if I try to connect textChanged signal to the function like following, it doesn't shows up.

QObject::connect(&MainWindow::ui->lineEdit, SIGNAL(&textChanged(QString)), this,SLOT(&MainWindow::on_lineEdit_editingFinished())); 

EDIT: Adding above line gives an error saying:

Expected constructor, destructor or type-conversion before ( token

Any help will be greatly appreciated.

Upvotes: 3

Views: 7620

Answers (2)

Jablonski
Jablonski

Reputation: 18504

Try to do it simply first, if the code works, then everything is good and you can start improving it.

In constructor:

QDir dir("G:/2");//path here
QStringList dirContents = dir.entryList(QStringList(), QDir::Files);
qDebug() << dirContents;//make sure that you list isn't empty, or use isEmpty method
QCompleter *fileEditCompleter = new QCompleter(dirContents, this);
fileEditCompleter->setCaseSensitivity(Qt::CaseInsensitive);
fileEditCompleter->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
ui->lineEdit->setCompleter(fileEditCompleter);

If this will work on your computer then you can be sure that your system and project are good, and start improve it (change list etc). And try not to use global variables.

If you want do it dynamically, create a simple model and when you will set new QStringList to it, your completer always will display new data

QDir dir("G:/2");
QStringList dirContents = dir.entryList(QStringList(), QDir::Files);

mdl = new QStringListModel(dirContents,this);//QStringListModel *mdl in header

QCompleter *fileEditCompleter = new QCompleter(mdl, this);
fileEditCompleter->setCaseSensitivity(Qt::CaseInsensitive);
fileEditCompleter->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
ui->lineEdit->setCompleter(fileEditCompleter);

When you want change data when for example, user clicks button or something else, you can do:

QDir dir("G:/2/tmp");
mdl->setStringList(dir.entryList(QStringList(), QDir::Files));

Now your completer has new data.

Upvotes: 6

Dmitry Sazonov
Dmitry Sazonov

Reputation: 8994

Converting comment to an answer, as requested...

Try to set completer before providing QLineEdit to user. For example - in constructor of MainWindow. It is not correct to set it in textChanged slot.

MainWindow::MainWindow()
  : QWidget(nullptr)
  , ui( new ui_MainWindow() )
{
  ui->setupUi(this);
  //...
  QCompleter *fileEditCompleter = new QCompleter(dirContents, this);
  fileEditCompleter->setCaseSensitivity(Qt::CaseInsensitive);
  fileEditCompleter->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
  ui->fileName_Edit->setCompleter(fileEditCompleter);
}

void MainWindow::on_lineEdit_textChanged(const QString &arg1)
{
  // Do nothing here
}

Upvotes: 3

Related Questions