Beispiel für einen benutzerdefinierten Vervollständiger
Das Beispiel „Benutzerdefinierter Vervollständiger“ zeigt, wie man für ein Eingabe-Widget Funktionen zur Zeichenfolgenvervollständigung bereitstellt, die auf den von einem Modell bereitgestellten Daten basieren. Der Vervollständiger zeigt Vorschläge für mögliche Wörter an, basierend auf den ersten drei vom Benutzer eingegebenen Zeichen, und das vom Benutzer ausgewählte Wort wird mithilfe von ` QTextCursor` in das ` TextEdit ` eingefügt.

Einrichten der Ressourcendatei
Das Beispiel „Benutzerdefinierter Vervollständiger“ benötigt eine Ressourcendatei namens „wordlist.txt“, die eine Liste von Wörtern enthält, anhand derer „ QCompleter “ Wörter vervollständigen kann. Diese Datei enthält Folgendes:
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/">
<file>resources/wordlist.txt</file>
</qresource>
</RCC>Definition der „TextEdit“-Klasse
Die Klasse „ TextEdit “ ist eine Unterklasse von „ QTextEdit “ mit einem benutzerdefinierten Slot „ insertCompletion() “ und implementiert die Funktionen „ keyPressEvent()“ sowie „ focusInEvent()“ neu. „ TextEdit “ enthält außerdem eine private Funktion „ textUnderCursor() “ sowie eine private Instanz von „ QCompleter “, „ c “.
class TextEdit : public QTextEdit
{
Q_OBJECT
public:
TextEdit(QWidget *parent = nullptr);
~TextEdit();
void setCompleter(QCompleter *c);
QCompleter *completer() const;
protected:
void keyPressEvent(QKeyEvent *e) override;
void focusInEvent(QFocusEvent *e) override;
private slots:
void insertCompletion(const QString &completion);
private:
QString textUnderCursor() const;
private:
QCompleter *c = nullptr;
};Implementierung der Klasse „TextEdit“
Der Konstruktor für TextEdit erstellt ein TextEdit mit einem übergeordneten Element und initialisiert c. Die Anleitung zur Verwendung der Vervollständigungsfunktion wird mithilfe der Funktion setPlainText() auf dem Objekt TextEdit angezeigt.
TextEdit::TextEdit(QWidget *parent)
: QTextEdit(parent)
{
setPlainText(tr("This TextEdit provides autocompletions for words that have more than"
" 3 characters. You can trigger autocompletion using ") +
QKeySequence("Ctrl+E").toString(QKeySequence::NativeText));
}Darüber hinaus enthält „ TextEdit “ auch einen Standard-Destruktor:
TextEdit::~TextEdit()
{
}Die Funktion ` setCompleter() ` nimmt ein ` completer ` entgegen und richtet es ein. Wir verwenden ` if (c) `, um zu prüfen, ob ` c ` initialisiert wurde. Ist dies der Fall, wird die Funktion ` QObject::disconnect()` aufgerufen, um die Verbindung zwischen Signal und Slot zu trennen. Damit soll sichergestellt werden, dass kein vorheriges Completer-Objekt mehr mit dem Slot verbunden ist.
void TextEdit::setCompleter(QCompleter *completer)
{
if (c)
c->disconnect(this);
c = completer;
if (!c)
return;
c->setWidget(this);
c->setCompletionMode(QCompleter::PopupCompletion);
c->setCaseSensitivity(Qt::CaseInsensitive);
QObject::connect(c, QOverload<const QString &>::of(&QCompleter::activated),
this, &TextEdit::insertCompletion);
}Anschließend instanziieren wir ` c ` mit ` completer ` und legen es als Widget von ` TextEdit` fest. Der Vervollständigungsmodus und die Groß-/Kleinschreibung werden ebenfalls festgelegt, und dann verbinden wir das Signal ` activated()` mit dem Slot ` insertCompletion() `.
Die Funktion „ completer() “ ist eine Getter-Funktion, die „ c “ zurückgibt.
QCompleter *TextEdit::completer() const
{
return c;
}Der Completer zeigt die verfügbaren Optionen basierend auf dem Inhalt von „wordlist.txt“ an, doch der Textcursor ist dafür zuständig, die fehlenden Zeichen entsprechend der Wortwahl des Benutzers einzufügen.
Angenommen, der Benutzer gibt „ACT“ ein und akzeptiert den Vorschlag des Completer „ACTUAL“. Die Zeichenkette „ completion “ wird dann über das Signal „ activated()“ des Completer an „ insertCompletion() “ gesendet.
Die Funktion „ insertCompletion() “ ist dafür zuständig, das Wort mithilfe eines „ QTextCursor “-Objekts („ tc “) zu vervollständigen. Sie führt eine Validierung durch, um sicherzustellen, dass das Widget des Vervollständigers den Status „ TextEdit “ hat, bevor sie mit „ tc “ die zusätzlichen Zeichen einfügt, um das Wort zu vervollständigen.
void TextEdit::insertCompletion(const QString &completion)
{
if (c->widget() != this)
return;
QTextCursor tc = textCursor();
int extra = completion.length() - c->completionPrefix().length();
tc.movePosition(QTextCursor::Left);
tc.movePosition(QTextCursor::EndOfWord);
tc.insertText(completion.right(extra));
setTextCursor(tc);
}Die folgende Abbildung veranschaulicht diesen Vorgang:

completion.length() = 6
c->completionPrefix().length()=3
Die Differenz zwischen diesen beiden Werten ist extra, also 3. Das bedeutet, dass die letzten drei Zeichen von rechts, „U“, „A“ und „L“, durch tc eingefügt werden.
Die Funktion „ textUnderCursor() “ verwendet „ QTextCursor “ („ tc “), um ein Wort unter dem Cursor auszuwählen und zurückzugeben.
QString TextEdit::textUnderCursor() const
{
QTextCursor tc = textCursor();
tc.select(QTextCursor::WordUnderCursor);
return tc.selectedText();
}Die Klasse „ TextEdit “ implementiert die Funktion „ focusInEvent()“ neu, bei der es sich um einen Ereignis-Handler handelt, der zum Empfangen von Tastaturfokus-Ereignissen für das Widget verwendet wird.
void TextEdit::focusInEvent(QFocusEvent *e)
{
if (c)
c->setWidget(this);
QTextEdit::focusInEvent(e);
}Die Funktion ` keyPressEvent()` wird neu implementiert, um Tastenereignisse wie ` Qt::Key_Enter`, ` Qt::Key_Return`, ` Qt::Key_Escape`, ` Qt::Key_Tab` und ` Qt::Key_Backtab ` zu ignorieren, damit der Komplettierer diese verarbeiten kann.
Wenn ein Vervollständiger aktiv ist, können wir die Tastenkombination Strg+E nicht verarbeiten.
void TextEdit::keyPressEvent(QKeyEvent *e)
{
if (c && c->popup()->isVisible()) {
// The following keys are forwarded by the completer to the widget
switch (e->key()) {
case Qt::Key_Enter:
case Qt::Key_Return:
case Qt::Key_Escape:
case Qt::Key_Tab:
case Qt::Key_Backtab:
e->ignore();
return; // let the completer do default behavior
default:
break;
}
}
const bool isShortcut = (e->modifiers().testFlag(Qt::ControlModifier) && e->key() == Qt::Key_E); // CTRL+E
if (!c || !isShortcut) // do not process the shortcut when we have a completer
QTextEdit::keyPressEvent(e);Wir behandeln auch andere Modifikatortasten und Tastenkombinationen, auf die der Vervollständiger nicht reagieren soll.
const bool ctrlOrShift = e->modifiers().testFlag(Qt::ControlModifier) ||
e->modifiers().testFlag(Qt::ShiftModifier);
if (!c || (ctrlOrShift && e->text().isEmpty()))
return;
static QString eow("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="); // end of word
const bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift;
QString completionPrefix = textUnderCursor();
if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 3
|| eow.contains(e->text().right(1)))) {
c->popup()->hide();
return;
}
if (completionPrefix != c->completionPrefix()) {
c->setCompletionPrefix(completionPrefix);
c->popup()->setCurrentIndex(c->completionModel()->index(0, 0));
}
QRect cr = cursorRect();
cr.setWidth(c->popup()->sizeHintForColumn(0)
+ c->popup()->verticalScrollBar()->sizeHint().width());
c->complete(cr); // popup it up!
}Schließlich zeigen wir den Komplettierer an.
Definition der Klasse „MainWindow“
Die Klasse „ MainWindow “ ist eine Unterklasse von „ QMainWindow “ und implementiert einen privaten Slot „ about() “. Diese Klasse verfügt außerdem über zwei private Funktionen, „ createMenu() “ und „ modelFromFile() “, sowie über private Instanzen von „ QCompleter “ und „ TextEdit “.
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
private slots:
void about();
private:
void createMenu();
QAbstractItemModel *modelFromFile(const QString& fileName);
QCompleter *completer = nullptr;
TextEdit *completingTextEdit;
};Implementierung der Klasse „MainWindow“
Der Konstruktor erstellt ein ` MainWindow ` mit einem übergeordneten Element und initialisiert das ` completer`. Außerdem instanziiert er ein ` TextEdit ` und legt dessen Komplettierer fest. Ein ` QStringListModel`, das aus ` modelFromFile()` abgerufen wird, wird verwendet, um das ` completer` zu füllen. Das zentrale Widget des ` MainWindow` wird auf ` TextEdit ` gesetzt und seine Größe auf 500 x 300 festgelegt.
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
createMenu();
completingTextEdit = new TextEdit;
completer = new QCompleter(this);
completer->setModel(modelFromFile(":/resources/wordlist.txt"));
completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
completer->setCaseSensitivity(Qt::CaseInsensitive);
completer->setWrapAround(false);
completingTextEdit->setCompleter(completer);
setCentralWidget(completingTextEdit);
resize(500, 300);
setWindowTitle(tr("Completer"));
}Die Funktion „ createMenu() “ erstellt die erforderlichen „ QAction “-Objekte, die für die Menüs „Datei“ und „Hilfe“ benötigt werden, und ihre „ triggered()“-Signale werden jeweils mit den Slots „ quit() “, „ about() “ und „ aboutQt() “ 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 ein „ fileName “ entgegen und versucht, den Inhalt dieser Datei in ein „ QStringListModel “ zu extrahieren. Wir zeigen das „ Qt::WaitCursor “ an, während wir das „ QStringList “ und das „ words “ füllen, und stellen den Mauszeiger wieder her, sobald wir fertig sind.
QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName)
{
QFile file(fileName);
if (!file.open(QFile::ReadOnly))
return new QStringListModel(completer);
#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();
#endif
return new QStringListModel(words, completer);
}Die Funktion „ about() “ liefert eine kurze Beschreibung des Beispiels „Custom Completer“.
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 „ 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.