QCompleter Makes Your Apps More User Friendly
In this blog post we'll look at a little-known feature of Qt that can make your applications more user friendly: the QCompleter class. QCompleter provides completions for user entry, based on an item model. It is supported by the QLineEdit and QComboBox widgets.
When a user enters text, the completer suggests possible ways of completing it, based on a word list provided by the model. The model can be any QAbstractItemModel, or in the simple case just a QStringList of words. Typically you create a QCompleter object, passing a model in the constructor. Widgets that support a completer have a setCompleter() method that allows specifying the completer to use for the widget.
A QCompleter supports a number of properties to control its behavior, including:
- whether completions should appear in a popup or in-line,
- whether the model is sorted,
- if completion matches should be based on what the entered string starts with, contains, or ends with,
- the maximum number of items that should be shown for the completions, and
- whether the match should be case sensitive.
A completer also supports emitting signals when the string match is highlighted or activated by the user.
These facilities are often enough for basic desktop applications. Another common use case is to help the user complete file paths by using a QFileSystemModel. If the underlying model is a more complex tree-based model, the class has support to accommodate this as well.
Completer Example
I wrote a simple example program that allows experimenting with QCompleter. It provides a line edit and combo box which are connected to a completer. You can change most of the completer properties from the UI and observe how the behavior changes. Below is a screen shot:
The model is a file of words which is loaded as a resource (I used the file /usr/share/dict/words which is found on many Linux systems). The code should be self-explanatory and can be downloaded from here.
Here is some of the relevant code that sets up the completer and widgets. First we open the file of words, read it, and create a string list (error checking is not shown here):
QFile file(QStringLiteral(":/words"));
file.open(QIODevice::ReadOnly|QIODevice::Text);
QTextStream in(&file);
QString s = in.readAll();
QStringList list = s.split('\n');
The completer is created passing the string list as the model:
completer = new QCompleter(list, this);
The line edit and combo box get associated with the completer:
ui->lineEdit->setCompleter(completer);
ui->comboBox->setEditable(true);
ui->comboBox->addItems(list);
ui->comboBox->setCompleter(completer);
That's pretty much it. The widgets on the screen that change the completer settings are connected to a slot that updates them using calls like this:
completer->setCompletionMode(QCompleter::PopupCompletion);
completer->setModelSorting(QCompleter::UnsortedModel);
completer->setFilterMode(Qt::MatchStartsWith);
completer->setMaxVisibleItems(ui->maxVisibleItemsSpinBox->value());
completer->setCaseSensitivity(Qt::CaseSensitive);
The highlighted() and activated() signals are connected to a slot that updates the status bar so you can see how they work. Here are a few more screen shots showing the completer being activated:
Conclusions
Qt comes with some example applications illustrating how QCompleter works. They can be found in your Qt install directory under examples/widgets/tools/completer, examples/widgets/tools/customcompleter, and examples/widgets/tools/treemodelcompleter.
You'll note that all these examples use widgets. There is no support for completers from QML, although that might make sense in the future as a feature to add to the Qt Quick Controls, which support ComboBox and TextField QML types much like Qt widgets.
If you found this interesting, check out more great technical content.