Exemple de compléteur de modèle d'arbre
L'exemple de compléteur de modèle arborescent montre comment fournir des fonctions de complétion pour un modèle hiérarchique, en utilisant un point comme séparateur pour accéder aux objets de niveau Enfant, Petit-enfant et Grand-petit-enfant.

Comme dans l'exemple de compléteur, nous fournissons des objets QComboBox pour permettre la sélection du mode de complétion et de la sensibilité à la casse, ainsi qu'un QCheckBox pour les complétions enveloppantes.
Le fichier de ressources
Le contenu du TreeModelCompleter est lu à partir du fichier treemodel.txt. Ce fichier est intégré au fichier de ressources treemodelcompleter.qrc, qui contient les éléments suivants :
<!DOCTYPE RCC><RCC version="1.0"> <qresource prefix="/"> <file>resources/treemodel.txt</file> </qresource> </RCC>
Définition de la classe TreeModelCompleter
La classe TreeModelCompleter est une sous-classe de QCompleter avec deux constructeurs - l'un avec parent comme argument et l'autre avec parent et model comme arguments.
class TreeModelCompleter : public QCompleter { Q_OBJECT Q_PROPERTY(QString separator READ separator WRITE setSeparator) public: explicit TreeModelCompleter(QObject *parent = nullptr); explicit TreeModelCompleter(QAbstractItemModel *model, QObject *parent = nullptr); QString separator() const; public slots: void setSeparator(const QString &separator); protected: QStringList splitPath(const QString &path) const override; QString pathFromIndex(const QModelIndex &index) const override; private: QString sep; };
La classe réimplémente les fonctions protégées splitPath() et pathFromIndex() pour les adapter à un modèle d'arbre. Pour plus d'informations sur l'adaptation de QCompleter aux modèles d'arbres, voir Handling Tree Models.
TreeModelCompleter possède également une propriété de séparateur qui est déclarée à l'aide de la macro Q_PROPERTY(). Le séparateur possède des attributs READ et WRITE et les fonctions correspondantes separator() et setSeparator(). Pour plus d'informations sur Q_PROPERTY(), reportez-vous au système de propriétés de Qt.
Mise en œuvre de la classe TreeModelCompleter
Le premier constructeur construit un objet TreeModelCompleter avec un parent, tandis que le second construit un objet avec un parent et QAbstractItemModel, model.
TreeModelCompleter::TreeModelCompleter(QObject *parent) : QCompleter(parent) { } TreeModelCompleter::TreeModelCompleter(QAbstractItemModel *model, QObject *parent) : QCompleter(model, parent) { }
La fonction separator() est une fonction getter qui renvoie la chaîne de séparation.
QString TreeModelCompleter::separator() const { return sep; }
Comme indiqué précédemment, la fonction splitPath() est réimplémentée car l'implémentation par défaut est plus adaptée aux modèles QFileSystemModel ou de liste. Pour que QCompleter divise le chemin d'accès en une liste de chaînes de caractères correspondant à chaque niveau, nous le divisons en utilisant QString::split() avec sep comme séparateur.
QStringList TreeModelCompleter::splitPath(const QString &path) const { return (sep.isNull() ? QCompleter::splitPath(path) : path.split(sep)); }
La fonction pathFromIndex() renvoie des données pour la fonction completionRole() d'un modèle d'arbre. Cette fonction est réimplémentée car son implémentation par défaut est plus adaptée aux modèles de liste. S'il n'y a pas de séparateur, nous utilisons l'implémentation par défaut de QCompleter, sinon nous utilisons la fonction prepend() pour naviguer vers le haut et accumuler les données. La fonction renvoie ensuite un QStringList, dataList, en utilisant un séparateur pour relier les objets de différents niveaux.
QString TreeModelCompleter::pathFromIndex(const QModelIndex &index) const { if (sep.isNull()) return QCompleter::pathFromIndex(index); // navigate up and accumulate data QStringList dataList; for (QModelIndex i = index; i.isValid(); i = i.parent()) dataList.prepend(model()->data(i, completionRole()).toString()); return dataList.join(sep); }
Définition de la classe MainWindow
La classe MainWindow est une sous-classe de QMainWindow et met en œuvre cinq emplacements personnalisés : about(), changeCase(), changeMode(), highlight(), et updateContentsLabel().
class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); private slots: void about(); void changeCase(int); void changeMode(int); void highlight(const QModelIndex &index); void updateContentsLabel(const QString &sep);
En outre, la classe possède deux fonctions privées, createMenu() et modelFromFile(), ainsi que des instances privées de QTreeView, QComboBox, QLabel, TreeModelCompleter et QLineEdit.
private: void createMenu(); QAbstractItemModel *modelFromFile(const QString &fileName); QTreeView *treeView = nullptr; QComboBox *caseCombo = nullptr; QComboBox *modeCombo = nullptr; QLabel *contentsLabel = nullptr; TreeModelCompleter *completer = nullptr; QLineEdit *lineEdit = nullptr; };
Mise en œuvre de la classe MainWindow
Le constructeur de MainWindow crée un objet MainWindow avec un parent et initialise les objets completer et lineEdit. La fonction createMenu() est invoquée pour configurer les menus "File" et "Help". Le modèle de completer est défini sur QAbstractItemModel obtenu à partir de modelFromFile(), et le signal highlighted() est connecté à l'emplacement highlight() de MainWindow.
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { createMenu(); completer = new TreeModelCompleter(this); completer->setModel(modelFromFile(":/resources/treemodel.txt")); completer->setSeparator(QLatin1String(".")); QObject::connect(completer, QOverload<const QModelIndex &>::of(&TreeModelCompleter::highlighted), this, &MainWindow::highlight); QWidget *centralWidget = new QWidget; QLabel *modelLabel = new QLabel; modelLabel->setText(tr("Tree Model<br>(Double click items to edit)")); 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);
Les objets QLabel modelLabel , modeLabel et caseLabel sont instanciés. Les objets QComboBox, modeCombo et caseCombo, sont également instanciés et peuplés. Par défaut, le mode de completer est "Filtered Popup" et la casse est insensible.
QLabel *separatorLabel = new QLabel; separatorLabel->setText(tr("Tree Separator")); QLineEdit *separatorLineEdit = new QLineEdit; separatorLineEdit->setText(completer->separator()); connect(separatorLineEdit, &QLineEdit::textChanged, completer, &TreeModelCompleter::setSeparator); QCheckBox *wrapCheckBox = new QCheckBox; wrapCheckBox->setText(tr("Wrap around completions")); wrapCheckBox->setChecked(completer->wrapAround()); connect(wrapCheckBox, &QAbstractButton::clicked, completer, &QCompleter::setWrapAround); contentsLabel = new QLabel; contentsLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); connect(separatorLineEdit, &QLineEdit::textChanged, this, &MainWindow::updateContentsLabel); treeView = new QTreeView; treeView->setModel(completer->model()); treeView->header()->hide(); treeView->expandAll(); connect(modeCombo, &QComboBox::activated, this, &MainWindow::changeMode); connect(caseCombo, &QComboBox::activated, this, &MainWindow::changeMode); lineEdit = new QLineEdit; lineEdit->setCompleter(completer);
Nous utilisons un QGridLayout pour placer tous les objets dans le MainWindow.
QGridLayout *layout = new QGridLayout; layout->addWidget(modelLabel, 0, 0); layout->addWidget(treeView, 0, 1); layout->addWidget(modeLabel, 1, 0); layout->addWidget(modeCombo, 1, 1); layout->addWidget(caseLabel, 2, 0); layout->addWidget(caseCombo, 2, 1); layout->addWidget(separatorLabel, 3, 0); layout->addWidget(separatorLineEdit, 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); changeCase(caseCombo->currentIndex()); changeMode(modeCombo->currentIndex()); setWindowTitle(tr("Tree Model Completer")); lineEdit->setFocus(); }
La fonction createMenu() met en place les objets QAction nécessaires et les ajoute au menu "File" et au menu "Help". Les signaux triggered() de ces 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 changeMode() accepte un index correspondant au mode d'achèvement choisi par l'utilisateur et modifie le mode du completer en conséquence.
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 about() fournit une brève description de l'exemple de compléteur de modèle d'arbre.
void MainWindow::about() { QMessageBox::about(this, tr("About"), tr("This example demonstrates how " "to use a QCompleter with a custom tree model.")); }
La fonction changeCase() alterne entre les modes Case Sensitive et Case Insensitive, en fonction de la valeur de cs.
void MainWindow::changeCase(int cs) { completer->setCaseSensitivity(cs ? Qt::CaseSensitive : Qt::CaseInsensitive); }
main() Fonction
La fonction main() instancie MainWindow et invoque la fonction show() pour l'afficher.
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.