Beispiel „Completer“
Das Completer-Beispiel zeigt, wie man für ein Eingabe-Widget Funktionen zur Zeichenfolgenvervollständigung bereitstellt, die auf den von einem Modell bereitgestellten Daten basieren.

Dieses Beispiel verwendet ein benutzerdefiniertes Elementmodell ( FileSystemModel) und ein „ QCompleter “-Objekt. „ QCompleter “ ist eine Klasse, die auf der Grundlage eines Elementmodells Vervollständigungsvorschläge bereitstellt. Der Modelltyp, der Vervollständigungsmodus und die Groß-/Kleinschreibung können über Kombinationsfelder ausgewählt werden.
Die Ressourcendatei
Das „Completer“-Beispiel benötigt eine Ressourcendatei, um die Dateien „countries.txt“ und „words.txt“ zu speichern. Die Ressourcendatei enthält den folgenden Code:
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/">
<file>resources/countries.txt</file>
<file>resources/wordlist.txt</file>
</qresource>
</RCC>Definition der Klasse „FileSystemModel“
Die Klasse „ FileSystemModel “ ist eine Unterklasse von „ QFileSystemModel “, die ein Datenmodell für das lokale Dateisystem bereitstellt.
class FileSystemModel : public QFileSystemModel
{
public:
FileSystemModel(QObject *parent = nullptr);
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
};Diese Klasse verfügt lediglich über einen Konstruktor und eine „ data() “-Funktion, da sie ausschließlich dazu dient, „ data() “ die Rückgabe des vollständigen Dateipfads für die Anzeigefunktion zu ermöglichen – im Gegensatz zur Funktion „ data() “ von „ QFileSystemModel “, die nur den Ordner und nicht die Laufwerksbezeichnung zurückgibt. Dies wird in der Implementierung von „ FileSystemModel “ näher erläutert.
Implementierung der Klasse „FileSystemModel“
Der Konstruktor der Klasse „ FileSystemModel “ dient dazu, „ parent “ an „ QFileSystemModel “ zu übergeben.
FileSystemModel::FileSystemModel(QObject *parent)
: QFileSystemModel(parent)
{
}Wie bereits erwähnt, wird die Funktion „ data() “ neu implementiert, damit sie den vollständigen Dateipfad für die Anzeige zurückgibt. Bei einem „ QFileSystemModel “ wird in der Ansicht beispielsweise „Program Files“ angezeigt. Bei „ FileSystemModel “ wird hingegen „C:\Program Files“ angezeigt.
QVariant FileSystemModel::data(const QModelIndex &index, int role) const
{
if (role == Qt::DisplayRole && index.column() == 0) {
QString path = QDir::toNativeSeparators(filePath(index));
if (path.endsWith(QDir::separator()))
path.chop(1);
return path;
}
return QFileSystemModel::data(index, role);
}Die Methode „ Qt::EditRole “, die von „ QCompleter “ zur Suche nach Übereinstimmungen verwendet wird, bleibt unverändert.
Definition der Klasse „MainWindow“
Die Klasse „ MainWindow “ ist eine Unterklasse von „ QMainWindow “ und implementiert fünf private Slots: „ about() “, „ changeCase() “, „ changeMode() “, „ changeModel() “ und „ changeMaxVisible() “.
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
private slots:
void about();
void changeCase(int);
void changeMode(int);
void changeModel();
void changeMaxVisible(int);Innerhalb der Klasse „ MainWindow “ gibt es zwei private Funktionen: „ createMenu() “ und „ modelFromFile() “. Außerdem werden die benötigten privaten Widgets deklariert – drei „ QComboBox “-Objekte, ein „ QCheckBox “, ein „ QCompleter “, ein „ QLabel “ und ein „ QLineEdit “.
private:
void createMenu();
QAbstractItemModel *modelFromFile(const QString &fileName);
QComboBox *caseCombo = nullptr;
QComboBox *modeCombo = nullptr;
QComboBox *modelCombo = nullptr;
QSpinBox *maxVisibleSpinBox = nullptr;
QCheckBox *wrapCheckBox = nullptr;
QCompleter *completer = nullptr;
QLabel *contentsLabel = nullptr;
QLineEdit *lineEdit = nullptr;
};Implementierung der Klasse „MainWindow“
Der Konstruktor von ` MainWindow ` erstellt ein ` MainWindow ` mit einem übergeordneten Widget und initialisiert die privaten Mitglieder. Anschließend wird die Funktion ` createMenu() ` aufgerufen.
Wir richten drei „ QComboBox “-Objekte ein: „ modelComb “, „ modeCombo “ und „ caseCombo “. Standardmäßig ist „ modelCombo “ auf „ QFileSystemModel “ gesetzt, „ modeCombo “ auf „Filtered Popup“ und „ caseCombo “ auf „Case Insensitive“.
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
createMenu();
QWidget *centralWidget = new QWidget;
QLabel *modelLabel = new QLabel;
modelLabel->setText(tr("Model"));
modelCombo = new QComboBox;
modelCombo->addItem(tr("QFileSystemModel"));
modelCombo->addItem(tr("QFileSystemModel that shows full path"));
modelCombo->addItem(tr("Country list"));
modelCombo->addItem(tr("Word list"));
modelCombo->setCurrentIndex(0);
QLabel *modeLabel = new QLabel;
modeLabel->setText(tr("Completion Mode"));
modeCombo = new QComboBox;
modeCombo->addItem(tr("Inline"));
modeCombo->addItem(tr("Filtered Popup"));
modeCombo->addItem(tr("Unfiltered Popup"));
modeCombo->setCurrentIndex(1);
QLabel *caseLabel = new QLabel;
caseLabel->setText(tr("Case Sensitivity"));
caseCombo = new QComboBox;
caseCombo->addItem(tr("Case Insensitive"));
caseCombo->addItem(tr("Case Sensitive"));
caseCombo->setCurrentIndex(0);Die „ maxVisibleSpinBox “ wird erstellt und legt die Anzahl der sichtbaren Einträge im Komplettierer fest
Anschließend wird das „ wrapCheckBox “ eingerichtet. Diese „ checkBox “ legt fest, ob die Eigenschaft „ setWrapAround()“ des „ completer “ aktiviert oder deaktiviert ist.
QLabel *maxVisibleLabel = new QLabel;
maxVisibleLabel->setText(tr("Max Visible Items"));
maxVisibleSpinBox = new QSpinBox;
maxVisibleSpinBox->setRange(3,25);
maxVisibleSpinBox->setValue(10);
wrapCheckBox = new QCheckBox;
wrapCheckBox->setText(tr("Wrap around completions"));
wrapCheckBox->setChecked(true);Wir instanziieren „ contentsLabel “ und legen dessen Größenrichtlinie auf „ fixed “ fest. Die „ activated()“-Signale der Kombinationsfelder werden anschließend mit ihren jeweiligen Slots verbunden.
contentsLabel = new QLabel;
contentsLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
connect(modelCombo, &QComboBox::activated,
this, &MainWindow::changeModel);
connect(modeCombo, &QComboBox::activated,
this, &MainWindow::changeMode);
connect(caseCombo, &QComboBox::activated,
this, &MainWindow::changeCase);
connect(maxVisibleSpinBox, &QSpinBox::valueChanged,
this, &MainWindow::changeMaxVisible);lineEdit wird eingerichtet, und anschließend ordnen wir alle Widgets mithilfe eines „ QGridLayout “ an. Die Funktion „ changeModel() “ wird aufgerufen, um die „ completer “ zu initialisieren.
lineEdit = new QLineEdit;
QGridLayout *layout = new QGridLayout;
layout->addWidget(modelLabel, 0, 0); layout->addWidget(modelCombo, 0, 1);
layout->addWidget(modeLabel, 1, 0); layout->addWidget(modeCombo, 1, 1);
layout->addWidget(caseLabel, 2, 0); layout->addWidget(caseCombo, 2, 1);
layout->addWidget(maxVisibleLabel, 3, 0); layout->addWidget(maxVisibleSpinBox, 3, 1);
layout->addWidget(wrapCheckBox, 4, 0);
layout->addWidget(contentsLabel, 5, 0, 1, 2);
layout->addWidget(lineEdit, 6, 0, 1, 2);
centralWidget->setLayout(layout);
setCentralWidget(centralWidget);
changeModel();
setWindowTitle(tr("Completer"));
lineEdit->setFocus();
}Die Funktion „ createMenu() “ wird verwendet, um die „ QAction “-Objekte zu instanziieren, die zum Füllen von „ fileMenu “ und „ helpMenu “ benötigt werden. Die Signale „ triggered()“ der Aktionen werden mit ihren jeweiligen Slots verbunden.
void MainWindow::createMenu()
{
QAction *exitAction = new QAction(tr("Exit"), this);
QAction *aboutAct = new QAction(tr("About"), this);
QAction *aboutQtAct = new QAction(tr("About Qt"), this);
connect(exitAction, &QAction::triggered, qApp, &QApplication::quit);
connect(aboutAct, &QAction::triggered, this, &MainWindow::about);
connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt);
QMenu *fileMenu = menuBar()->addMenu(tr("File"));
fileMenu->addAction(exitAction);
QMenu *helpMenu = menuBar()->addMenu(tr("About"));
helpMenu->addAction(aboutAct);
helpMenu->addAction(aboutQtAct);
}Die Funktion ` modelFromFile() ` nimmt den ` fileName ` einer Datei entgegen und verarbeitet ihn je nach Inhalt.
Zunächst überprüfen wir den ` file `, um sicherzustellen, dass er im Modus `QFile::ReadOnly` geöffnet werden kann. Gelingt dies nicht, gibt die Funktion einen leeren ` QStringListModel` zurück.
QAbstractItemModel *MainWindow::modelFromFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QFile::ReadOnly))
return new QStringListModel(completer);Anschließend wird der Mauszeiger durch „ Qt::WaitCursor “ überschrieben, bevor wir ein „ QStringList “-Objekt, „ words “, mit dem Inhalt von „ file “ füllen. Sobald dies geschehen ist, stellen wir den Mauszeiger wieder her.
#ifndef QT_NO_CURSOR
QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
#endif
QStringList words;
while (!file.atEnd()) {
QByteArray line = file.readLine();
if (!line.isEmpty())
words << QString::fromUtf8(line.trimmed());
}
#ifndef QT_NO_CURSOR
QGuiApplication::restoreOverrideCursor();
#endifWie bereits erwähnt, enthält die Ressourcen-Datei zwei Dateien – „countries.txt“ und „words.txt“. Wenn der gelesene Wert von „ file “ „words.txt“ lautet, geben wir ein „ QStringListModel “-Objekt zurück, dessen „ QStringList “ „ words “ und dessen „ completer “ „parent“ ist.
if (!fileName.contains(QLatin1String("countries.txt")))
return new QStringListModel(words, completer);Wird bei „ file “ die Datei „countries.txt“ gelesen, benötigen wir eine „ QStandardItemModel “ mit „ words.count() “ Zeilen, 2 Spalten und „ completer “ als übergeordnetem Element.
QStandardItemModel *m = new QStandardItemModel(words.count(), 2, completer);Eine Standardzeile in „countries.txt“ lautet:
Norway NO
Um das „ QStandardItemModel “-Objekt „ m “ zu füllen, müssen wir daher den Ländernamen und sein Symbol trennen. Sobald dies geschehen ist, geben wir „ m “ zurück.
for (int i = 0; i < words.count(); ++i) {
QModelIndex countryIdx = m->index(i, 0);
QModelIndex symbolIdx = m->index(i, 1);
QString country = words.at(i).mid(0, words[i].length() - 2).trimmed();
QString symbol = words.at(i).right(2);
m->setData(countryIdx, country);
m->setData(symbolIdx, symbol);
}
return m;
}Die Funktion „ changeMode() “ legt den Modus von „ completer “ fest, abhängig vom Wert von „ index “.
void MainWindow::changeMode(int index)
{
QCompleter::CompletionMode mode;
if (index == 0)
mode = QCompleter::InlineCompletion;
else if (index == 1)
mode = QCompleter::PopupCompletion;
else
mode = QCompleter::UnfilteredPopupCompletion;
completer->setCompletionMode(mode);
}Die Funktion „ changeModel() “ ändert das verwendete Elementmodell entsprechend dem vom Benutzer ausgewählten Modell.
Eine ` switch `-Anweisung wird verwendet, um das Elementmodell basierend auf dem Index von ` modelCombo` zu ändern. Ist ` case ` gleich 0, verwenden wir ein unsortiertes ` QFileSystemModel`, wodurch wir einen Dateipfad ohne Laufwerksbezeichnung erhalten.
void MainWindow::changeModel()
{
delete completer;
completer = new QCompleter(this);
completer->setMaxVisibleItems(maxVisibleSpinBox->value());
switch (modelCombo->currentIndex()) {
default:
case 0:
{ // Unsorted QFileSystemModel
QFileSystemModel *fsModel = new QFileSystemModel(completer);
fsModel->setRootPath(QString());
completer->setModel(fsModel);
contentsLabel->setText(tr("Enter file path"));
}
break;Beachten Sie, dass wir das Modell mit „ completer “ als übergeordnetem Element erstellen, da wir so das Modell durch ein neues ersetzen können. „ completer “ stellt sicher, dass das alte Modell gelöscht wird, sobald ihm ein neues Modell zugewiesen wird.
Ist „ case “ gleich 1, verwenden wir das zuvor definierte „ DirModel “, was zu vollständigen Dateipfaden führt.
case 1:
{ // FileSystemModel that shows full paths
FileSystemModel *fsModel = new FileSystemModel(completer);
completer->setModel(fsModel);
fsModel->setRootPath(QString());
contentsLabel->setText(tr("Enter file path"));
}
break;Wenn „ case “ den Wert 2 hat, versuchen wir, Ländernamen zu vervollständigen. Dazu ist ein „ QTreeView “-Objekt erforderlich: treeView. Die Ländernamen werden aus der Datei „countries.txt“ extrahiert, und das Popup zur Anzeige der Vervollständigungsvorschläge wird auf treeView gesetzt.
case 2:
{ // Country List
completer->setModel(modelFromFile(":/resources/countries.txt"));
QTreeView *treeView = new QTreeView;
completer->setPopup(treeView);
treeView->setRootIsDecorated(false);
treeView->header()->hide();
treeView->header()->setStretchLastSection(false);
treeView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
treeView->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
contentsLabel->setText(tr("Enter name of your country"));
}
break;Der folgende Screenshot zeigt den „Completer“ mit dem Modell „countries.txt“.

Wenn „ case “ den Wert 3 hat, versuchen wir, Wörter zu vervollständigen. Dies geschieht mithilfe eines „ QStringListModel “, das Daten aus der Datei „words.txt“ enthält. Das Modell ist sortiert case insensitively.
Der folgende Screenshot zeigt den „Completer“ mit dem Wortlistenmodell.

Sobald der Modelltyp ausgewählt ist, rufen wir die Funktionen „ changeMode() “ und „ changeCase() “ auf und legen die Option „wrap“ entsprechend fest. Das Signal „ clicked()“ des „ wrapCheckBox “ wird mit dem Slot „ setWrapAround()“ des „ completer “ verbunden.
case 3:
{ // Word list
completer->setModel(modelFromFile(":/resources/wordlist.txt"));
completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
contentsLabel->setText(tr("Enter a word"));
}
break;
}
changeMode(modeCombo->currentIndex());
changeCase(caseCombo->currentIndex());
completer->setWrapAround(wrapCheckBox->isChecked());
lineEdit->setCompleter(completer);
connect(wrapCheckBox, &QAbstractButton::clicked, completer, &QCompleter::setWrapAround);
}Die Funktion „ changeMaxVisible() “ aktualisiert die maximale Anzahl der sichtbaren Elemente im Completer.
void MainWindow::changeMaxVisible(int max)
{
completer->setMaxVisibleItems(max);
}Die Funktion „ about() “ enthält eine kurze Beschreibung des Beispiels.
void MainWindow::about()
{
QMessageBox::about(this, tr("About"), tr("This example demonstrates the "
"different features of the QCompleter class."));
}main() Funktion
Die Funktion „ main() “ instanziiert „ QApplication “ und „ MainWindow “ und ruft die Funktion „ show()“ auf.
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.