Exemple de compléteur personnalisé
L'exemple de compléteur personnalisé montre comment fournir des fonctions de complétion de chaîne de caractères pour un widget de saisie basé sur des données fournies par un modèle. Le compléteur affiche des suggestions de mots possibles en fonction des trois premiers caractères saisis par l'utilisateur et le mot choisi par l'utilisateur est inséré dans le site TextEdit à l'aide de QTextCursor.

Configuration du fichier de ressources
L'exemple de compléteur personnalisé nécessite un fichier de ressources, wordlist.txt, qui contient une liste de mots pour aider QCompleter à compléter des mots. Ce fichier contient les éléments suivants :
<!DOCTYPE RCC><RCC version="1.0"> <qresource prefix="/"> <file>resources/wordlist.txt</file> </qresource> </RCC>
Définition de la classe TextEdit
La classe TextEdit est une sous-classe de QTextEdit avec un slot insertCompletion() personnalisé et elle réimplémente les fonctions keyPressEvent() et focusInEvent(). TextEdit contient également une fonction privée textUnderCursor() et une instance privée de 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; };
Mise en œuvre de la classe TextEdit
Le constructeur de TextEdit construit un TextEdit avec un parent et initialise c. Les instructions d'utilisation du compléteur sont affichées sur l'objet TextEdit, à l'aide de la fonction setPlainText().
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)); }
En outre, TextEdit comprend également un destructeur par défaut :
TextEdit::~TextEdit() { }
La fonction setCompleter() accepte un completer et l'initialise. Nous utilisons if (c) pour vérifier si c a été initialisé. Si c'est le cas, la fonction QObject::disconnect() est invoquée pour déconnecter le signal de la fente. Cela permet de s'assurer qu'aucun objet de complétion précédent n'est encore connecté à la fente.
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); }
Nous instancions ensuite c avec completer et le définissons comme le widget de TextEdit. Le mode de complétion et la sensibilité à la casse sont également définis, puis nous connectons le signal activated() à l'emplacement insertCompletion().
La fonction completer() est une fonction d'obtention qui renvoie c.
QCompleter *TextEdit::completer() const { return c; }
Le compléteur affiche les options disponibles, sur la base du contenu de wordlist.txt, mais le curseur de texte est chargé de compléter les caractères manquants, en fonction du mot choisi par l'utilisateur.
Supposons que l'utilisateur saisisse "ACT" et accepte la suggestion du compléteur, à savoir "ACTUEL". La chaîne completion est alors envoyée à insertCompletion() par le signal activated() du compléteur.
La fonction insertCompletion() est chargée de compléter le mot à l'aide d'un objet QTextCursor, tc. Elle vérifie que le widget du compléteur est bien TextEdit avant d'utiliser tc pour insérer les caractères supplémentaires afin de compléter le mot.
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); }
La figure ci-dessous illustre ce processus :

completion.length() = 6
c->completionPrefix().length()=3
La différence entre ces deux valeurs est extra, qui vaut 3. Cela signifie que les trois derniers caractères de la droite, "U", "A" et "L", seront insérés par tc.
La fonction textUnderCursor() utilise un QTextCursor, tc, pour sélectionner un mot sous le curseur et le renvoyer.
QString TextEdit::textUnderCursor() const { QTextCursor tc = textCursor(); tc.select(QTextCursor::WordUnderCursor); return tc.selectedText(); }
La classe TextEdit réimplémente la fonction focusInEvent(), qui est un gestionnaire d'événements utilisé pour recevoir les événements de mise au point du clavier pour le widget.
void TextEdit::focusInEvent(QFocusEvent *e) { if (c) c->setWidget(this); QTextEdit::focusInEvent(e); }
La fonction keyPressEvent() est réimplémentée pour ignorer les événements de touches comme Qt::Key_Enter, Qt::Key_Return, Qt::Key_Escape, Qt::Key_Tab, et Qt::Key_Backtab afin que le compléteur puisse les gérer.
Si un compléteur est actif, nous ne pouvons pas traiter le raccourci Ctrl+E.
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);
Nous traitons également d'autres modificateurs et raccourcis pour lesquels nous ne voulons pas que le compléteur réponde.
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! }
Enfin, nous faisons apparaître le compléteur.
Définition de la classe MainWindow
La classe MainWindow est une sous-classe de QMainWindow et implémente un slot privé, about(). Cette classe possède également deux fonctions privées, createMenu() et modelFromFile(), ainsi que des instances privées de QCompleter et 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; };
Mise en œuvre de la classe MainWindow
Le constructeur crée un MainWindow avec un parent et initialise le completer. Il instancie également un TextEdit et définit son compléteur. Un QStringListModel, obtenu à partir de modelFromFile(), est utilisé pour remplir le completer. Le widget central du MainWindow est fixé à TextEdit et sa taille est fixée à 500 x 300.
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")); }
La fonction createMenu() crée les objets QAction nécessaires pour les menus "File" et "Help" et leurs signaux triggered() sont connectés aux emplacements quit(), about() et aboutQt() respectivement.
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); }
La fonction modelFromFile() accepte un fileName et tente d'extraire le contenu de ce fichier dans un QStringListModel. Nous affichons le Qt::WaitCursor lorsque nous remplissons les QStringList, words, et restaurons le curseur de la souris lorsque nous avons terminé.
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); }
La fonction about() fournit une brève description de l'exemple de Custom Completer.
void MainWindow::about() { QMessageBox::about(this, tr("About"), tr("This example demonstrates the " "different features of the QCompleter class.")); }
main() Fonction
La fonction main() instancie MainWindow et invoque la fonction show().
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.