Qt Quick Controls - Text-Editor
Eine Rich-Text-Editor-Anwendung mit Qt Quick Controls.
Das Texteditor-Beispiel ermöglicht die WYSIWYG-Bearbeitung einer HTML-, Markdown- oder reinen Textdatei. Die Anwendung verfügt über zwei Benutzeroberflächen: eine für größere Bildschirme und eine vereinfachte Benutzeroberfläche für kleine Touch-basierte Geräte. Beide sind "reines" QML. texteditor.cpp
enthält die Funktion main()
, die QFontDatabase::addApplicationFont() aufruft, um eine Symbolschriftart hinzuzufügen. (FontLoader wäre eine Alternative, um das gleiche Ergebnis zu erzielen).
Desktop-Benutzeroberfläche
Die Desktop-Version ist ein vollständiger Texteditor mit Möglichkeiten zur Textformatierung und zum Öffnen und Speichern von HTML-, Markdown- und reinen Textdateien.
Beim Model-View-Control (MVC)-Entwurfsmuster umfasst die Steuerebene eine Reihe von Operationen, die ausgeführt werden können. In Qt Quick Controls wird der Typ Action verwendet, um einen einzelnen Vorgang oder Befehl zu kapseln. Dementsprechend beginnen wir mit einer Reihe von Action-Objekten:
Action { id: openAction text: qsTr("&Open") shortcut: StandardKey.Open onTriggered: { if (textArea.textDocument.modified) discardDialog.open() else openDialog.open() } }
Das Action zum Öffnen einer Datei muss den Benutzer zunächst fragen, ob das vorhandene Dokument geändert wurde, um zu vermeiden, dass die Änderungen des Benutzers verloren gehen. Andernfalls öffnet es einfach das FileDialog, das weiter unten erklärt wird.
Die Funktion Action zum Speichern der Datei wird nur aktiviert, wenn es Änderungen zu speichern gibt:
Action { id: saveAction text: qsTr("&Save…") shortcut: StandardKey.Save enabled: textArea.textDocument.modified onTriggered: textArea.textDocument.save() }
Die Action zum Kopieren von markiertem Text wird nur aktiviert, wenn Text markiert ist:
Action { id: copyAction text: qsTr("&Copy") shortcut: StandardKey.Copy enabled: textArea.selectedText onTriggered: textArea.copy() }
Jede Aktion zur Änderung der Textformatierung (z. B. fett, kursiv und Ausrichtung) ist checkable, und ihr boolescher checked
Zustand ist mit der entsprechenden Eigenschaft in selected text synchronisiert. Da eine deklarative bidirektionale Synchronisierung schwierig ist, verwenden wir ein onTriggered
Skript, um die Eigenschaft zu ändern, wenn die Aktion aktiviert wird. Die cursorSelection Eigenschaft ist neu in Qt 6.7 und macht dies viel einfacher als zuvor.
Action { id: boldAction text: qsTr("&Bold") shortcut: StandardKey.Bold checkable: true checked: textArea.cursorSelection.font.bold onTriggered: textArea.cursorSelection.font = Qt.font({ bold: checked }) } Action { id: alignCenterAction text: qsTr("&Center") shortcut: "Ctrl+|" checkable: true checked: textArea.cursorSelection.alignment === Qt.AlignCenter onTriggered: textArea.cursorSelection.alignment = Qt.AlignCenter }
Wir haben eine MenuBar, die die Hierarchie von Menus und MenuItems enthält. Jedes MenuItem muss lediglich das entsprechende action binden, das die UI-Darstellung und die Implementierung kapselt.
menuBar: MenuBar { Menu { title: qsTr("&File") MenuItem { action: openAction } MenuItem { action: saveAction } MenuItem { action: saveAsAction } MenuItem { action: quitAction } } Menu { title: qsTr("&Edit") MenuItem { action: copyAction } ...
Dieselben Action -Objekte werden in ToolBar wiederverwendet, aber hier überschreiben wir die text -Eigenschaft jeder Aktion, um ein Textsymbol aus unserer Symbolschriftart auszuwählen:
header: ToolBar { leftPadding: 8 Flow { id: flow width: parent.width Row { id: fileRow ToolButton { id: openButton text: "\uF115" // icon-folder-open-empty font.family: "fontello" action: openAction focusPolicy: Qt.TabFocus } ToolButton { id: saveButton text: "\uE80A" // icon-floppy-disk font.family: "fontello" action: saveAction focusPolicy: Qt.TabFocus } ToolSeparator { contentItem.visible: fileRow.y === editRow.y } } Row { id: editRow ToolButton { id: copyButton text: "\uF0C5" // icon-docs font.family: "fontello" focusPolicy: Qt.TabFocus action: copyAction } ...
Der Hauptteil des Texteditors ist ein TextArea innerhalb eines Flickable:
Flickable { id: flickable flickableDirection: Flickable.VerticalFlick anchors.fill: parent ScrollBar.vertical: ScrollBar {} TextArea.flickable: TextArea { id: textArea textFormat: Qt.AutoText wrapMode: TextArea.Wrap focus: true selectByMouse: true persistentSelection: true ...
Ein ScrollBar ist mit der vertikalen Achse verbunden. Da der Wortumbruch über wrapMode aktiviert ist, benötigen wir keine horizontale ScrollBar.
Die Eigenschaft TextArea.flickable attached wird verwendet, damit, wenn der Textcursor aus dem Ansichtsfenster herausbewegt wird (z. B. über Pfeiltasten oder durch Eingabe von viel Text), TextArea den Flickable scrollt, damit der Cursor sichtbar bleibt.
Es gibt ein Kontextmenü; wir verwenden ein TapHandler, um einen Rechtsklick zu erkennen und es zu öffnen:
TapHandler { acceptedButtons: Qt.RightButton onTapped: contextMenu.popup() }
Das Kontextmenü Menu enthält MenuItems, das dieselben Action Objekte wiederverwendet, die auch die Hauptobjekte MenuBar und ToolBar verwenden. Wie zuvor reicht es aus, action an die wiederverwendbare Aktion zu binden, die die auszuführende Operation darstellt. Wir überschreiben jedoch die text jedes Menüeintrags, um die unterstrichenen Mnemonics im Kontextmenü wegzulassen.
Wir verwenden konsequent die Funktion qsTr(), um die Übersetzung von UI-Text zu ermöglichen, damit die Anwendung unabhängig von der Muttersprache des Endbenutzers Sinn macht.
Wir verwenden mehrere Arten von dialogs:
FileDialog { id: openDialog fileMode: FileDialog.OpenFile selectedNameFilter.index: 1 nameFilters: ["Text files (*.txt)", "HTML files (*.html *.htm)", "Markdown files (*.md *.markdown)"] currentFolder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation) onAccepted: { textArea.textDocument.modified = false // we asked earlier, if necessary textArea.textDocument.source = selectedFile } } FileDialog { id: saveDialog fileMode: FileDialog.SaveFile nameFilters: openDialog.nameFilters currentFolder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation) onAccepted: textArea.textDocument.saveAs(selectedFile) } FontDialog { id: fontDialog onAccepted: textArea.cursorSelection.font = selectedFont } ColorDialog { id: colorDialog selectedColor: "black" onAccepted: textArea.cursorSelection.color = selectedColor } MessageDialog { title: qsTr("Error") id: errorDialog } MessageDialog { id : quitDialog title: qsTr("Quit?") text: qsTr("The file has been modified. Quit anyway?") buttons: MessageDialog.Yes | MessageDialog.No onButtonClicked: function (button, role) { if (role === MessageDialog.YesRole) { textArea.textDocument.modified = false Qt.quit() } } } MessageDialog { id : discardDialog title: qsTr("Discard changes?") text: qsTr("The file has been modified. Open a new file anyway?") buttons: MessageDialog.Yes | MessageDialog.No onButtonClicked: function (button, role) { if (role === MessageDialog.YesRole) openDialog.open() } }
Im Allgemeinen ist es einfacher, für jeden Zweck separate Instanzen zu deklarieren. Wir haben zwei Instanzen von FileDialog, zum Öffnen bzw. Speichern von Dateien. Dies wurde in Qt 6.7 mit den neuen Funktionen von TextDocument einfacher.
Ein FontDialog und ein ColorDialog ermöglichen die Änderung der Textformatierung. (Im Markdown-Format gibt es keine Syntax, um bestimmte Schriftarten und -farben darzustellen, aber Schriftartenmerkmale wie fett, kursiv und Monospace werden gespeichert. Im HTML-Format werden alle Formatierungen gespeichert.)
Wir haben eine MessageDialog, um Fehlermeldungen anzuzeigen, und zwei weitere, um den Benutzer aufzufordern, was zu tun ist, wenn eine Datei geändert wurde.
Touch-Benutzeroberfläche
Die Touch-Benutzeroberfläche ist eine vereinfachte Version des Texteditors. Sie ist für Touch-Geräte mit begrenzter Bildschirmgröße geeignet. Das Beispiel verwendet Dateiselektoren, um die entsprechende Benutzeroberfläche automatisch zu laden.
Ausführen des Beispiels
Zum Ausführen des Beispiels von Qt Creatorzu starten, öffnen Sie den Modus Welcome und wählen Sie das Beispiel aus Examples. Weitere Informationen finden Sie unter Erstellen und Ausführen eines Beispiels.
© 2025 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.