Auf dieser Seite

Qt Quick Controls - Texteditor

Eine Rich-Text-Editor-App, die „ Qt Quick Controls “ nutzt.

Das Texteditor-Beispiel ermöglicht die WYSIWYG-Bearbeitung von HTML-, Markdown- oder Nur-Text-Dateien. Die Anwendung verfügt über zwei Benutzeroberflächen: eine für größere Bildschirme und eine vereinfachte Benutzeroberfläche für kleine Touch-Geräte. Beide sind in „reinem“ QML geschrieben. „ texteditor.cpp “ enthält die Funktion „ main() “, die „ QFontDatabase::addApplicationFont()“ aufruft, um eine Icon-Schriftart hinzuzufügen. (FontLoader wäre eine alternative Möglichkeit, um dasselbe Ergebnis zu erzielen.)

Desktop-Benutzeroberfläche

Texteditor mit Menüleiste, Symbolleiste und formatiertem Dokumentinhalt

Die Desktop-Version ist ein vollwertiger Texteditor mit Funktionen zur Textformatierung sowie zum Öffnen und Speichern von HTML-, Markdown- und Nur-Text-Dateien.

Im Entwurfsmuster „Model-View-Control“ (MVC) umfasst die Control-Schicht die Gesamtheit der durchführbaren Operationen. In „ Qt Quick Controls “ wird der Typ „ Action “ verwendet, um eine einzelne Operation oder einen 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()
        }
    }

Die „ Action “ zum Öffnen einer Datei muss den Benutzer zunächst fragen, ob das vorhandene Dokument geändert wurde, um den Verlust der Änderungen des Benutzers zu vermeiden. Andernfalls öffnet sie einfach die „ FileDialog “, die weiter unten deklariert ist.

Die „ Action “ zum Speichern der Datei wird nur aktiviert, wenn Änderungen zum Speichern vorhanden sind:

    Action {
        id: saveAction
        text: qsTr("&Save…")
        shortcut: StandardKey.Save
        enabled: textArea.textDocument.modified
        onTriggered: textArea.textDocument.save()
    }

Die „ Action “ zum Kopieren von ausgewähltem Text ist nur aktiviert, wenn Text ausgewählt ist:

    Action {
        id: copyAction
        text: qsTr("&Copy")
        shortcut: StandardKey.Copy
        enabled: textArea.selectedText
        onTriggered: textArea.copy()
    }

Jede Aktion zur Änderung der Textformatierung (wie Fettdruck, Kursivschrift und Ausrichtung) ist eine „ checkable “, und ihr boolescher Status „ checked “ ist mit der entsprechenden Eigenschaft im „ selected text “ synchronisiert. Da eine deklarative bidirektionale Synchronisation schwierig ist, verwenden wir ein „ onTriggered “-Skript, um die Eigenschaft zu ändern, wenn die Aktion aktiviert wird. Die Eigenschaft ` cursorSelection ` ist neu in Qt 6.7 und macht dies wesentlich einfacher als zuvor.

    Action {
        id: boldAction
        text: qsTr("&Bold")
        shortcut: StandardKey.Bold
        checkable: true
        checked: textArea.cursorSelection.font.bold
        onTriggered: textArea.cursorSelection.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
            }
        ...

Die gleichen „ Action “-Objekte werden im „ ToolBar “ wiederverwendet; hier überschreiben wir jedoch die „ text “-Eigenschaft jeder „Action“, um ein Text-Icon aus unserer Icon-Schriftart auszuwählen:

    header: ToolBar {
        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 an der vertikalen Achse angebracht. Da der Zeilenumbruch über „ wrapMode “ aktiviert ist, benötigen wir kein horizontales „ ScrollBar “.

Die angehängte Eigenschaft „ TextArea.flickable “ wird verwendet, damit „ TextArea “ den „ Flickable “ scrollt, wenn der Textcursor aus dem Ansichtsbereich verschoben wird (z. B. über die Pfeiltasten oder durch Eingabe von viel Text), um den Cursor sichtbar zu halten.

Wir übernehmen die gleichen Aktionen, die wir in „ MenuBar “ und „ ToolBar “ deklariert haben, und fügen sie den vorhandenen Elementen im Standard- context menu hinzu, der von „ TextArea “ bereitgestellt wird:

                const menu = textArea.ContextMenu.menu
                menu.addItem(menuSeparatorComponent.createObject(menu.contentItem))
                menu.addAction(fontDialogAction)
                menu.addAction(colorDialogAction)

Wir verwenden durchgängig die Funktion ` qsTr()` zur Übersetzung von UI-Text, damit die Anwendung unabhängig von der Muttersprache des Endnutzers verständlich bleibt.

Wir verwenden verschiedene 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: textArea.cursorSelection.color
        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`, jeweils zum Öffnen und Speichern von Dateien. Dies wurde in Qt 6.7 durch neue Funktionen in ` TextDocument` vereinfacht.

Ein „ FontDialog “ und ein „ ColorDialog “ ermöglichen es, die Textformatierung zu ändern. (Im Markdown-Format gibt es keine Syntax zur Darstellung spezifischer Schriftarten und Farben; Schriftmerkmale wie Fettdruck, Kursivschrift und Monospace-Schrift werden jedoch gespeichert. Im HTML-Format wird die gesamte Formatierung gespeichert.)

Wir haben ein „ MessageDialog “, um Fehlermeldungen anzuzeigen, sowie zwei weitere, um den Benutzer aufzufordern, was zu tun ist, wenn eine Datei geändert wurde.

Touch-Benutzeroberfläche

Texteditor-Oberfläche für Touch-Geräte mit Formatierungsleiste

Die Touch-Benutzeroberfläche ist eine vereinfachte Version des Texteditors. Sie eignet sich für Touch-Geräte mit begrenzter Bildschirmgröße. Das Beispiel verwendet Dateiauswahlfelder, um die entsprechende Benutzeroberfläche automatisch zu laden.

Ausführen des Beispiels

Sie können das Beispiel wie folgt ausführen:

Beispielprojekt @ code.qt.io

© 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.