Qt Quick Controls - テキストエディタ
Qt Quick Controls を使用したリッチテキストエディタ アプリです。
Text Editor Exampleでは、HTML、Markdown、またはプレーンテキストファイルを WYSIWYG で編集できます。このアプリケーションには2つのユーザーインターフェイスがあります:1つは大きなスクリーン用、もう1つは小さなタッチベースのデバイス用の簡素化されたUIです。どちらも "純粋な "QMLです。texteditor.cpp
にはmain()
関数が含まれており、QFontDatabase::addApplicationFont() を呼び出してアイコンフォントを追加します。(FontLoader は同じ結果を得るための別の方法です。)
デスクトップユーザーインターフェイス
デスクトップ版は、テキストの書式設定、HTML、Markdown、プレーンテキストファイルのオープンと保存が可能な、完全なテキストエディタです。
モデル・ビュー・コントロール(MVC)デザイン・パターンでは、コントロール・レイヤは実行可能な操作のセットを含みます。Qt Quick Controlsでは、Action 型を使用して、単一の操作やコマンドをカプセル化します。したがって、Actionオブジェクトのセットから始めます:
Action { id: openAction text: qsTr("&Open") shortcut: StandardKey.Open onTriggered: { if (textArea.textDocument.modified) discardDialog.open() else openDialog.open() } }
ファイルを開くためのAction は、ユーザーの変更が失われるのを避けるために、既存のドキュメントが変更された場合、まずユーザーにプロンプトを表示する必要があります。そうでなければ、FileDialog を開くだけである。
ファイルを保存するAction は、保存する変更がある場合にのみ有効になります:
Action { id: saveAction text: qsTr("&Save…") shortcut: StandardKey.Save enabled: textArea.textDocument.modified onTriggered: textArea.textDocument.save() }
選択されたテキストをコピーするAction は、テキストが選択されている場合のみ有効です:
Action { id: copyAction text: qsTr("&Copy") shortcut: StandardKey.Copy enabled: textArea.selectedText onTriggered: textArea.copy() }
テ キ ス ト の書式設定 (太字、 斜体、 整列な ど) を変更す る 各ア ク シ ョ ンはcheckable であ り 、 その論理値checked
の状態はselected text の関連プ ロ パテ ィ と 同期 し ます。 宣言的な双方向同期は難しいので、onTriggered
ス ク リ プ ト を用いて、 ア ク シ ョ ンがア ク テ ィ ブに さ れた と き にプ ロ パテ ィ を変更 し ます。cursorSelection プロパティは Qt 6.7 の新機能で、以前よりずっと簡単になりました。
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 }
Menus と MenuItems の階層を含むMenuBar があります。各MenuItem は、UI 表現と実装をカプセル化した関連するaction をバインドするだけです。
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 } ...
同じAction オブジェクトがToolBar で再利用されますが、ここでは各Actionのtext プロパティをオーバーライドして、アイコンフォントからテキストアイコンを選択します:
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 } ...
テキストエディタの主要部分は、Flickable の中にあるTextArea です:
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 ...
ScrollBar が縦軸に取り付けられています。単語の折り返しはwrapMode で有効になっているので、横方向のScrollBar は必要ありません。
TextArea.flickable のアタッチド・プロパティは、テキスト・カーソルが(矢印キーや大量のテキスト入力などで)ビューポートの外に移動すると、TextArea がFlickable をスクロールしてカーソルを表示し続けるために使用されます。
コンテキストメニューがあります。TapHandler を使って右クリックを検出し、それを開きます:
TapHandler { acceptedButtons: Qt.RightButton onTapped: contextMenu.popup() }
コンテキストMenu には、メインのMenuBar とToolBar が使っているのと同じAction オブジェクトを再利用するMenuItems が含まれています。以前と同じように、action を、実行する操作を表す再利用可能なアクションにバインドするだけで十分です。ただし、各メニュー項目のtext をオーバーライドして、コンテキスト・メニューの下線のニーモニックを省略する。
エンドユーザーの母国語に関係なくアプリケーションが理解できるように、UIテキストの翻訳を可能にするために、一貫してqsTr ()関数を使用しています。
私たちはいくつかの種類の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() } }
一般的に、それぞれの目的のために別々のインスタンスを宣言する方が簡単です。私たちはFileDialog の2つのインスタンスを持っています。Qt 6.7 では、TextDocument の新機能により、より簡単になりました。
FontDialog とColorDialog はテキストのフォーマットを変更することができます。(Markdownフォーマットでは、特定のフォントや色の選択を表す構文はありませんが、太字、斜体、等幅などのフォントの特性は保存されます。HTMLフォーマットでは、すべてのフォーマットが保存されます)。
エラーメッセージを表示するためのMessageDialog 、ファイルが変更されたときにユーザーに何をすべきかを促すための2つのプロンプトがあります。
タッチ・ユーザー・インターフェース
タッチ・ユーザー・インターフェースはテキストエディタの簡易版です。画面サイズの限られたタッチ・デバイスに適している。この例では、ファイル・セレクタを使って適切なユーザー・インターフェースを自動的にロードします。
例の実行
Qt Creator からサンプルを実行するには、Welcome モードを開き、Examples からサンプルを選択します。詳細については、Building and Running an Example を参照してください。
©2024 The Qt Company Ltd. 本書に含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 ここで提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。