L'interface QTextCursor
Les documents peuvent être édités via l'interface fournie par la classe QTextCursor; les curseurs sont soit créés à l'aide d'un constructeur, soit obtenus à partir d'un widget d'éditeur. Le curseur est utilisé pour effectuer des opérations d'édition qui correspondent exactement à celles que l'utilisateur peut effectuer lui-même dans un éditeur. Par conséquent, les informations relatives à la structure du document sont également disponibles via le curseur, ce qui permet de modifier la structure. L'utilisation d'une interface orientée curseur pour l'édition simplifie le processus d'écriture d'un éditeur personnalisé pour les développeurs, puisque les opérations d'édition peuvent être facilement visualisées.
La classe QTextCursor conserve également des informations sur le texte qu'elle a sélectionné dans le document, toujours selon un modèle conceptuellement similaire aux actions effectuées par l'utilisateur pour sélectionner du texte dans un éditeur.
Plusieurs curseurs peuvent être associés aux documents de texte enrichi et chacun d'entre eux contient des informations sur sa position dans le document et sur les sélections qu'il peut contenir. Ce paradigme basé sur le curseur rend les opérations courantes, telles que couper et coller du texte, simples à mettre en œuvre par programme, mais il permet également d'effectuer des opérations d'édition plus complexes sur le document.
Ce chapitre décrit la plupart des opérations d'édition courantes que vous devrez effectuer à l'aide d'un curseur, de l'insertion de base de texte et d'éléments de document à la manipulation plus complexe des structures du document.
Édition à l'aide d'un curseur
Au niveau le plus simple, les documents texte sont constitués d'une chaîne de caractères, marqués d'une manière ou d'une autre pour représenter la structure en blocs du texte dans le document. QTextCursor fournit une interface basée sur le curseur qui permet de manipuler le contenu d'un site QTextDocument au niveau des caractères. Étant donné que les éléments (blocs, cadres, tableaux, etc.) sont également codés dans le flux de caractères, la structure du document peut elle-même être modifiée par le curseur.
Le curseur garde la trace de son emplacement dans le document parent et peut fournir des informations sur la structure environnante, telle que le bloc de texte, le cadre, le tableau ou la liste qui l'entoure. Les formats des structures environnantes peuvent également être obtenus directement par le curseur.
Utilisation d'un curseur
La principale utilisation d'un curseur est l'insertion ou la modification de texte à l'intérieur d'un bloc. Pour ce faire, nous pouvons utiliser le curseur d'un éditeur de texte :
QTextEdit *editor = new QTextEdit(); QTextCursor cursor(editor->textCursor());
Il est également possible d'obtenir un curseur directement à partir d'un document :
QTextDocument *document = new QTextDocument(editor); QTextCursor cursor(document);
Le curseur est positionné au début du document de manière à ce que nous puissions écrire dans le premier bloc (vide) du document.
Regroupement des opérations de curseur
Une série d'opérations d'édition peut être regroupée de manière à pouvoir être rejouée ou annulée en une seule action. Pour ce faire, il suffit d'utiliser les fonctions beginEditBlock() et endEditBlock() de la manière suivante, comme dans l'exemple suivant où nous sélectionnons le mot qui contient le curseur :
cursor.beginEditBlock(); cursor.movePosition(QTextCursor::StartOfWord); cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor); cursor.endEditBlock();
Si les opérations d'édition ne sont pas groupées, le document enregistre automatiquement les opérations individuelles afin de pouvoir les annuler ultérieurement. Le regroupement des opérations dans des ensembles plus vastes peut rendre l'édition plus efficace à la fois pour l'utilisateur et pour l'application, mais il faut veiller à ne pas regrouper trop d'opérations, car l'utilisateur peut souhaiter un contrôle plus fin sur le processus d'annulation.
Curseurs multiples
Plusieurs curseurs peuvent être utilisés pour éditer simultanément le même document, bien qu'un seul soit visible par l'utilisateur dans un widget QTextEdit. Le site QTextDocument veille à ce que chaque curseur écrive du texte correctement et n'interfère pas avec les autres.
Insertion d'éléments de document
QTextCursor fournit plusieurs fonctions qui peuvent être utilisées pour modifier la structure d'un document de texte enrichi. En général, ces fonctions permettent de créer des éléments de document avec les informations de mise en forme appropriées et de les insérer dans le document à la position du curseur.
Le premier groupe de fonctions insère des éléments au niveau du bloc et met à jour la position du curseur, mais ne renvoie pas l'élément qui a été inséré :
- insertBlock() insère un nouveau bloc de texte (paragraphe) dans un document à la position du curseur, et déplace le curseur au début du nouveau bloc.
- insertFragment() insère un fragment de texte existant dans un document à la position du curseur.
- insertImage() insère une image dans un document à la position du curseur.
- insertText() insère du texte dans le document à la position du curseur.
Vous pouvez examiner le contenu de l'élément inséré via l'interface du curseur.
Le deuxième groupe de fonctions insère des éléments qui fournissent une structure au document et renvoie la structure qui a été insérée :
- insertFrame() insère un cadre dans le document après le bloc actuel du curseur et déplace le curseur au début du bloc vide dans le nouveau cadre.
- insertList() insère une liste dans le document à la position du curseur et déplace le curseur au début du premier élément de la liste.
- insertTable() insère un tableau dans le document après le bloc actuel du curseur et déplace le curseur au début du bloc suivant le tableau.
Ces éléments contiennent ou regroupent d'autres éléments dans le document.
Texte et fragments de texte
Le texte peut être inséré dans le bloc courant dans le format de caractère courant ou dans un format personnalisé spécifié avec le texte :
cursor.insertText(tr("Character formats"), headingFormat); cursor.insertBlock(); cursor.insertText(tr("Text can be displayed in a variety of " "different character formats. "), plainFormat); cursor.insertText(tr("We can emphasize text by ")); cursor.insertText(tr("making it italic"), emphasisFormat);
Une fois que le format de caractères a été utilisé avec un curseur, ce format devient le format par défaut pour tout texte inséré avec ce curseur jusqu'à ce qu'un autre format de caractères soit spécifié.
Si un curseur est utilisé pour insérer du texte sans spécifier de format de caractère, le texte recevra le format de caractère utilisé à cette position dans le document.
Blocs
Les blocs de texte sont insérés dans le document à l'aide de la fonction insertBlock().
QTextBlockFormat backgroundFormat = blockFormat; backgroundFormat.setBackground(QColor("lightGray")); cursor.setBlockFormat(backgroundFormat);
Le curseur est positionné au début du nouveau bloc.
Cadres
Les cadres sont insérés dans un document à l'aide du curseur et seront placés dans le cadre actuel du curseur après le bloc actuel. Le code suivant montre comment un cadre peut être inséré entre deux blocs de texte dans le cadre racine d'un document. Nous commençons par trouver le cadre courant du curseur :
QTextFrame *mainFrame = cursor.currentFrame();
cursor.insertText(...);Nous insérons du texte dans ce cadre, puis nous définissons un format de cadre pour le cadre enfant :
QTextFrameFormat frameFormat; frameFormat.setMargin(32); frameFormat.setPadding(8); frameFormat.setBorder(4);
Le format de cadre donnera au cadre une marge externe de 32 pixels, un rembourrage interne de 8 pixels et une bordure de 4 pixels de large. Pour plus d'informations sur les formats de cadre, consultez la documentation de QTextFrameFormat.
Le cadre est inséré dans le document après le texte précédent :
cursor.insertFrame(frameFormat);
cursor.insertText(...);Nous ajoutons du texte au document immédiatement après l'insertion du cadre. Étant donné que le curseur de texte est positionné à l'intérieur du cadre lorsqu'il est inséré dans le document, ce texte sera également inséré à l'intérieur du cadre.
Enfin, nous positionnons le curseur à l'extérieur du cadre en prenant la dernière position disponible du curseur à l'intérieur du cadre que nous avons enregistrée précédemment :
cursor = mainFrame->lastCursorPosition();
cursor.insertText(...);Le texte que nous ajoutons en dernier est inséré après le cadre enfant dans le document. Étant donné que chaque cadre est complété par des blocs de texte, il est toujours possible d'insérer davantage d'éléments à l'aide d'un curseur.
Tableaux
Les tableaux sont insérés dans le document à l'aide du curseur et sont placés dans le cadre actuel du curseur après le bloc actuel :
QTextCursor cursor(editor->textCursor()); QTextTable *table = cursor.insertTable(rows, columns, tableFormat);
Les tableaux peuvent être créés avec un format spécifique qui définit les propriétés générales du tableau, telles que son alignement, sa couleur de fond et l'espacement des cellules utilisé. Il peut également déterminer les contraintes sur chaque colonne, permettant à chacune d'entre elles d'avoir une largeur fixe ou de se redimensionner en fonction de l'espace disponible.
QTextTableFormat tableFormat; tableFormat.setBackground(QColor("#e0e0e0")); QList<QTextLength> constraints; constraints << QTextLength(QTextLength::PercentageLength, 16); constraints << QTextLength(QTextLength::PercentageLength, 28); constraints << QTextLength(QTextLength::PercentageLength, 28); constraints << QTextLength(QTextLength::PercentageLength, 28); tableFormat.setColumnWidthConstraints(constraints); QTextTable *table = cursor.insertTable(rows, columns, tableFormat);
Les colonnes du tableau créé ci-dessus occuperont chacune un certain pourcentage de la largeur disponible. Notez que le format du tableau est facultatif ; si vous insérez un tableau sans format, des valeurs par défaut raisonnables seront utilisées pour les propriétés du tableau.
Les cellules pouvant contenir d'autres éléments du document, elles peuvent également être formatées et stylisées si nécessaire.
Du texte peut être ajouté au tableau en naviguant dans chaque cellule avec le curseur et en insérant du texte.
cell = table->cellAt(0, 0); cellCursor = cell.firstCursorPosition(); cellCursor.insertText(tr("Week"), charFormat);
Nous pouvons créer un emploi du temps simple en suivant cette approche :
for (column = 1; column < columns; ++column) { cell = table->cellAt(0, column); cellCursor = cell.firstCursorPosition(); cellCursor.insertText(tr("Team %1").arg(column), charFormat); } for (row = 1; row < rows; ++row) { cell = table->cellAt(row, 0); cellCursor = cell.firstCursorPosition(); cellCursor.insertText(tr("%1").arg(row), charFormat); for (column = 1; column < columns; ++column) { if ((row-1) % 3 == column-1) { cell = table->cellAt(row, column); QTextCursor cellCursor = cell.firstCursorPosition(); cellCursor.insertText(tr("On duty"), charFormat); } } }
Listes
Des listes d'éléments de bloc peuvent être créées automatiquement et insérées dans le document à la position actuelle du curseur. Chaque liste ainsi créée nécessite la spécification d'un format de liste :
QTextListFormat listFormat; if (list) { listFormat = list->format(); listFormat.setIndent(listFormat.indent() + 1); } listFormat.setStyle(QTextListFormat::ListDisc); cursor.insertList(listFormat);
Le code ci-dessus vérifie d'abord si le curseur se trouve dans une liste existante et, si c'est le cas, donne au format de la nouvelle liste un niveau d'indentation approprié. Cela permet de créer des listes imbriquées avec des niveaux d'indentation croissants. Une implémentation plus sophistiquée utiliserait également différents types de symboles pour les puces à chaque niveau de la liste.
Images
Les images en ligne sont ajoutées aux documents par l'intermédiaire du curseur de la manière habituelle. Contrairement à de nombreux autres éléments, toutes les propriétés de l'image sont spécifiées par son format. Cela signifie qu'un objet QTextImageFormat doit être créé avant qu'une image puisse être insérée :
QTextImageFormat imageFormat; imageFormat.setName(":/images/advert.png"); cursor.insertImage(imageFormat);
Le nom de l'image fait référence à une entrée du fichier de ressources de l'application. La méthode utilisée pour dériver ce nom est décrite dans Le système de ressources Qt.
Exemples de textes enrichis
Le texte enrichi est stocké dans des documents textuels qui peuvent être créés en important du HTML à partir d'une source externe ou générés à l'aide d'un site QTextCursor.
Manipuler du texte enrichi
La manière la plus simple d'utiliser un document de texte enrichi est d'utiliser la classe QTextEdit, qui fournit une vue éditable d'un document. Le code ci-dessous importe du HTML dans un document et affiche le document à l'aide d'un widget d'édition de texte.
QTextEdit *editor = new QTextEdit(parent); editor->setHtml(aStringContainingHTMLtext); editor->show();
Vous pouvez récupérer le document à partir de l'éditeur de texte à l'aide de la fonction document(). Le document peut ensuite être édité par programme à l'aide de la classe QTextCursor. Cette classe est modelée sur un curseur d'écran, et les opérations d'édition suivent la même sémantique. Le code suivant modifie la première ligne du document avec une police en gras, en laissant toutes les autres propriétés de la police intactes. L'éditeur sera automatiquement mis à jour pour refléter les modifications apportées aux données du document sous-jacent.
QTextDocument *document = edit->document(); QTextCursor cursor(document); cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); QTextCharFormat format; format.setFontWeight(QFont::Bold); cursor.mergeCharFormat(format);
Notez que le curseur a été déplacé du début de la première ligne à la fin, mais qu'il a conservé un ancrage au début de la ligne. Ceci démontre les possibilités de sélection basées sur le curseur de la classe QTextCursor.
Générer un calendrier
Un texte riche peut être généré très rapidement en utilisant l'approche basée sur le curseur. L'exemple suivant montre un calendrier simple dans un widget QTextEdit avec des en-têtes en gras pour les jours de la semaine :
editor = new QTextEdit(this); QTextCursor cursor(editor->textCursor()); cursor.movePosition(QTextCursor::Start); QTextCharFormat format(cursor.charFormat()); format.setFontFamilies({"Courier"}); QTextCharFormat boldFormat = format; boldFormat.setFontWeight(QFont::Bold); cursor.insertBlock(); cursor.insertText(" ", boldFormat); QDate date = QDate::currentDate(); int year = date.year(), month = date.month(); for (int weekDay = 1; weekDay <= 7; ++weekDay) { cursor.insertText(QString("%1 ").arg(QLocale::system().dayName(weekDay), 3), boldFormat); } cursor.insertBlock(); cursor.insertText(" ", format); for (int column = 1; column < QDate(year, month, 1).dayOfWeek(); ++column) { cursor.insertText(" ", format); } for (int day = 1; day <= date.daysInMonth(); ++day) { int weekDay = QDate(year, month, day).dayOfWeek(); if (QDate(year, month, day) == date) cursor.insertText(QString("%1 ").arg(day, 3), boldFormat); else cursor.insertText(QString("%1 ").arg(day, 3), format); if (weekDay == 7) { cursor.insertBlock(); cursor.insertText(" ", format); } }
L'exemple ci-dessus montre à quel point il est simple de générer rapidement de nouveaux documents en texte riche en utilisant un minimum de code. Bien que nous ayons généré un calendrier grossier à pas fixe pour éviter de citer trop de code, Scribe offre des fonctionnalités de mise en page et de formatage beaucoup plus sophistiquées.
© 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.