Exemple de compléteur
L'exemple de compléteur montre comment fournir des fonctions de complétion de chaîne pour un widget de saisie basé sur des données fournies par un modèle.

Cet exemple utilise un modèle d'élément personnalisé, FileSystemModel, et un objet QCompleter. QCompleter est une classe qui fournit des compléments basés sur un modèle d'élément. Le type de modèle, le mode de complétion et la sensibilité à la casse peuvent être sélectionnés à l'aide de listes déroulantes.
Le fichier de ressources
L'exemple de compléteur nécessite un fichier de ressources afin de stocker les fichiers countries.txt et words.txt. Le fichier de ressources contient le code suivant :
<!DOCTYPE RCC><RCC version="1.0"> <qresource prefix="/"> <file>resources/countries.txt</file> <file>resources/wordlist.txt</file> </qresource> </RCC>
Définition de la classe FileSystemModel
La classe FileSystemModel est une sous-classe de QFileSystemModel, qui fournit un modèle de données pour le système de fichiers local.
class FileSystemModel : public QFileSystemModel { public: FileSystemModel(QObject *parent = nullptr); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; };
Cette classe ne possède qu'un constructeur et une fonction data(), car elle n'est créée que pour permettre à data() de renvoyer l'intégralité du chemin d'accès au fichier pour le rôle d'affichage, contrairement à la fonction data() de QFileSystemModel qui ne renvoie que le dossier et non l'étiquette du lecteur. Ceci est expliqué plus en détail dans l'implémentation de FileSystemModel.
Mise en œuvre de la classe FileSystemModel
Le constructeur de la classe FileSystemModel est utilisé pour transmettre parent à QFileSystemModel.
FileSystemModel::FileSystemModel(QObject *parent) : QFileSystemModel(parent) { }
Comme indiqué précédemment, la fonction data() est réimplémentée afin qu'elle renvoie l'intégralité du chemin d'accès au fichier pour le rôle d'affichage. Par exemple, avec QFileSystemModel, vous verrez "Program Files" dans la vue. Cependant, avec FileSystemModel, vous verrez "C :\Program Files".
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); }
L'adresse Qt::EditRole, que QCompleter utilise pour rechercher des correspondances, reste inchangée.
Définition de la classe MainWindow
La classe MainWindow est une sous-classe de QMainWindow et met en œuvre cinq emplacements privés - about(), changeCase(), changeMode(), changeModel() et 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);
Dans la classe MainWindow, nous avons deux fonctions privées : createMenu() et modelFromFile(). Nous déclarons également les widgets privés nécessaires - trois objets QComboBox, un QCheckBox, un QCompleter, un QLabel et un 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; };
Mise en œuvre de la classe MainWindow
Le constructeur de MainWindow construit un MainWindow avec un widget parent et initialise les membres privés. La fonction createMenu() est ensuite invoquée.
Nous créons trois objets QComboBox, modelComb, modeCombo et caseCombo. Par défaut, l'objet modelCombo est défini sur QFileSystemModel, l'objet modeCombo est défini sur "Filtered Popup" et l'objet caseCombo est défini sur "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);
Le site maxVisibleSpinBox est créé et détermine le nombre d'éléments visibles dans la fenêtre d'information.
Le site wrapCheckBox est ensuite créé. Cette checkBox détermine si la propriété setWrapAround() de completer est activée ou désactivée.
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);
Nous instancions contentsLabel et définissons sa politique de taille sur fixed. Les signaux activated() des combo-boxes sont ensuite connectés à leurs emplacements respectifs.
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);
La fonction lineEdit est configurée, puis nous disposons tous les widgets à l'aide d'une fonction QGridLayout. La fonction changeModel() est appelée pour initialiser la fonction completer.
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(); }
La fonction createMenu() est utilisée pour instancier les objets QAction nécessaires pour remplir les fileMenu et helpMenu. Les signaux triggered() des actions sont connectés à leurs emplacements respectifs.
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 le fileName d'un fichier et le traite en fonction de son contenu.
Nous validons d'abord le file pour nous assurer qu'il peut être ouvert en mode QFile::ReadOnly. En cas d'échec, la fonction renvoie un QStringListModel vide.
QAbstractItemModel *MainWindow::modelFromFile(const QString &fileName) { QFile file(fileName); if (!file.open(QFile::ReadOnly)) return new QStringListModel(completer);
Le curseur de la souris est alors remplacé par Qt::WaitCursor avant que nous ne remplissions un objet QStringList, words, avec le contenu de file. Une fois que cela est fait, nous restaurons le curseur de la souris.
#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
Comme indiqué précédemment, le fichier de ressources contient deux fichiers - countries.txt et words.txt. Si le fichier file lu est words.txt, nous renvoyons un QStringListModel avec words comme QStringList et completer comme parent.
if (!fileName.contains(QLatin1String("countries.txt"))) return new QStringListModel(words, completer);
Si le fichier file lu est countries.txt, nous demandons un QStandardItemModel avec words.count() lignes, 2 colonnes, et completer comme parent.
QStandardItemModel *m = new QStandardItemModel(words.count(), 2, completer);
Une ligne standard dans countries.txt est la suivante :
Norvège NO
Par conséquent, pour remplir l'objet QStandardItemModel, m, nous devons séparer le nom du pays et son symbole. Une fois cette opération effectuée, nous renvoyons m.
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; }
La fonction changeMode() définit le mode de completer en fonction de la valeur de 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); }
La fonction changeModel() modifie le modèle d'élément utilisé en fonction du modèle sélectionné par l'utilisateur.
Une instruction switch est utilisée pour changer le modèle d'élément en fonction de l'index de modelCombo. Si case est 0, nous utilisons un QFileSystemModel non trié, ce qui nous fournit un chemin de fichier excluant l'étiquette du lecteur.
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;
Notez que nous créons le modèle avec completer comme parent, car cela nous permet de remplacer le modèle par un nouveau modèle. Le site completer veillera à ce que l'ancien modèle soit supprimé dès qu'un nouveau modèle lui sera attribué.
Si case vaut 1, nous utilisons le DirModel que nous avons défini plus tôt, ce qui donne des chemins complets pour les fichiers.
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;
Lorsque case vaut 2, nous essayons de compléter les noms des pays. Cela nécessite un objet QTreeView, treeView. Les noms de pays sont extraits de countries.txt et la fenêtre contextuelle utilisée pour afficher les complétions est réglée sur treeView.
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;
La capture d'écran ci-dessous montre le compléteur avec le modèle de liste de pays.

Si case vaut 3, nous essayons de compléter les mots. Pour ce faire, nous utilisons un site QStringListModel qui contient des données extraites de words.txt. Le modèle est trié par case insensitively.
La capture d'écran ci-dessous montre le modèle de liste de mots.

Une fois le type de modèle sélectionné, nous appelons les fonctions changeMode() et changeCase() et définissons l'option wrap en conséquence. Le signal clicked() de wrapCheckBox est connecté à l'emplacement setWrapAround() de completer.
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); }
La fonction changeMaxVisible() met à jour le nombre maximum d'éléments visibles dans le compléteur.
void MainWindow::changeMaxVisible(int max) { completer->setMaxVisibleItems(max); }
La fonction about() fournit une brève description de l'exemple.
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 QApplication et 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.