为什么使用带有自动完成的QLineEdit和QCompleter时无法显示?

3

我在程序中有两个QLineEdit,分别为lineEditfileName_EditlineEdit保存着用户输入的目录地址。然后,用户在fileName_Edit中输入文件名。当用户正在输入文件名时,我希望向他显示建议。尝试使用以下方式实现QCompleter:
(dirContents是一个QStringList,它保存着由用户在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);
}

程序编译成功,但自动完成器没有出现。即使我尝试将textChanged信号连接到函数,如下所示,它也不会出现。

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

编辑:添加上述行会出现错误,错误信息如下:
预期构造函数、析构函数或类型转换前应有 ( 标记
非常感谢您的帮助。

1
尝试在向用户提供QLineEdit之前设置自动补全器。例如,在MainWindow的构造函数中设置。在textChanged槽中设置是不正确的。 - Dmitry Sazonov
@DmitrySazonov 感谢您的回复,您能否给出一些示例代码? - Amol Borkar
我认为在lineEdit之前不需要创建Completer。Qt文档也是这样做的。但在textChanged槽中这样做,不确定是否好。而且dirContents从哪里来并不完全清楚。你确定它不是空的吗?你确定已经调用了这个方法吗?也许你想用editingFinished信号来调用它? - Benjamin Maurer
2个回答

6

首先尝试简单地完成它,如果代码能够正常工作,那么一切都很好,你可以开始改进它。

在构造函数中:

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);

如果这可以在您的计算机上运行,那么您可以确定您的系统和项目良好,并开始改进它(更改列表等)。尽量不要使用全局变量。
如果您希望动态地执行此操作,请创建一个简单的模型,并在将新的QStringList设置为它时,您的自动完成器始终会显示新数据。
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);

当你想在用户点击按钮或其他事件发生时更改数据,你可以这样做:
QDir dir("G:/2/tmp");
mdl->setStringList(dir.entryList(QStringList(), QDir::Files));

现在您的自动补全器有了新数据。

谢谢!它起作用了。我想问一下,如果我将您代码中的QDir部分放在一个函数内,然后将其与QLineEdit信号连接,那么它会起作用吗?我需要做其他的函数来传递QDir对象吗? - Amol Borkar
1
@EdwardMckinzie 如您所见,我们需要在此处使用 QDir 来获取文件列表,您可以在任何地方使用此 QDir 但您的列表应该在您想要使用它的所有地方都可见,因为对您来说最重要的是列表以及此列表中的信息,QDir 只是一个工具。我希望这可以帮助您。还有一点:如果您发现我的和其他答案有用,请投票支持(按上面的三角形按钮)?谢谢。http://stackoverflow.com/help/why-vote - Jablonski
嘿,有没有办法在程序中稍后修改dirContents的内容,例如使用QLineEdit或其他什么?如果可以,怎么做呢?这是因为当构造函数运行时,它只有QDir dir()中路径下的文件,而没有用户在lineEdit中输入的内容。所以无论我在lineEdit中输入哪个路径,Qcompleter都会显示dir()目录中存在的文件。我的做法是错误的吗?并且我不认为构造函数可以在类/程序启动后调用。所以你能否建议一种解决上述问题的方法?我会查看你的其他答案。 - Amol Borkar
@EdwardMckinzie 如果我将 QDir dir("G:/2/tmp"); mdl->setStringList(dir.entryList(QStringList(), QDir::Files)); 设置到 buttonClicked 槽中,当我成功按下按钮时,它会更改模型中的数据。 - Jablonski
是的,我已将QDir dir("G:/2/tmp"); mdl->setStringList(dir.entryList(QStringList(), QDir::Files));放到一个“pushButton clicked”槽中,但它没有起作用,我不知道为什么。 - Amol Borkar
显示剩余2条评论

3

按照要求,将评论转换为答案...

尝试在向用户提供QLineEdit之前设置自动补全器。例如,在MainWindow的构造函数中设置。不应该在textChanged槽函数中设置。

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
}

实际上,dirContents是一个全局变量,它的值来自另一个本地qstringlist。所以当我尝试你的方法时,它会给我一个错误,说“dirContents在此范围内未声明” :( - Amol Borkar
我通过创建一个返回dirContents的函数来解决了上述错误。但问题是,它似乎仍然无法正常工作。有什么想法吗? - Amol Borkar
1
+1,楼主的代码看起来非常复杂,可能存在许多错误。我建议他从简单的东西开始,逐步做更加复杂的事情。 - Jablonski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接