QMLと のベストプラクティスQt Quick
QMLとQt Quick は、多くの利点があるにもかかわらず、状況によっては、難 しい場合があります。以下のセクションでは、アプリケーションを開発する際に、より良い結果を得るためのベストプラクティスについて詳しく説明します。
カスタムUIコントロール
流動的でモダンな UI は、今日の世界でアプリケーションを成功させるための鍵であり、 QML はデザイナーや開発者にとって非常に意味のあるものです。Qtは、流動的でモダンなUIを作成するために必要な、最も基本的なUIコントロールを提供しています。独自のUIコントロールを作成する前に、このUIコントロールのリストを参照することをお勧めします。
Qt Quick 自体が提供するこれらの基本的な UI コントロールの他に、Qt Quick Controls では豊富な UI コントロールのセットも利用できます。これらのUIコントロールは、最も一般的なユースケースにそのまま対応し、カスタマイズオプションでより多くの可能性を提供します。特にQt Quick Controls 、最新のUIデザイントレンドに沿ったスタイリングオプションを提供しています。これらのUIコントロールがアプリケーションのニーズを満たさない場合は、カスタムコントロールを作成することをお勧めします。
Qt Design Studioさらに、タイムラインベースのアニメーション、視覚効果、レイアウト、アプリケーションのプロトタイピングのためのライブプレビューを提供します。
関連情報
コーディング規約
QMLコーディング規約を参照してください。
アプリケーションリソースのバンドル
ほとんどのアプリケーションは、リッチなユーザーエクスペリエンスを提供するために、画像やアイコンのようなリソースに依存しています。これらのリソースを、ターゲットOSに関係なくアプリケーションで利用できるようにすることは、しばしば困難な課題となります。一般的なOSの多くは、ファイルシステムへのアクセスを制限する厳格なセキュリティポリシーを採用しているため、これらのリソースをロードすることが難しくなっています。その代替として、Qt はアプリケーション・バイナリに組み込まれた独自のリソース・システムを提供し、ターゲット OS に関係なくアプリケーションのリソースにアクセスできるようにします。
例えば、次のようなプロジェクトのディレクトリ構造を考えてみましょう:
MyModule ├── images │ ├── image1.png │ └── image2.png ├── CMakeLists.txt └── main.qml
この構造をCMake QMLモジュールとして表現すると、次のようになります:
qt_add_qml_module(my_module URI MyModule VERSION 1.0 QML_FILES main.qml RESOURCES images/image1.png images/image2.png # ... )
QML_FILES
の下にリストされている全ての QML ファイルは、事前に自動的にコンパイルされます。
QMLファイルはCMakeLists.txtのqt_add_qml_moduleと同じディレクトリに置いてください。そうしないと、暗黙のインポートが所属するQML モジュールと異なってしまいます。これはよくある間違いの原因です。
関連情報
UI とビジネスロジックの分離
ほとんどのアプリケーション開発者が達成したい重要な目標の1つは、保守性の高いアプリケーションを作ることです。この目標を達成する方法の一つは、ユーザーインターフェースをビジネスロジックから分離することです。以下に、アプリケーションのUIをQMLで記述すべきいくつかの理由を示します:
- 宣言型言語はUIの定義に適している。
- QML のコードは C++ よりも冗長でなく、強く型付けされていないため、書くのが簡単です。そのため、プロトタイプを作成するのに適した言語であり、デザイナーと共同作業をする際などには欠かせない言語です。
- JavaScriptはQMLの中で、イベントへの応答に簡単に使うことができます。
強く型付けされた言語であるC++は、アプリケーションのビジネスロジックに 最適です。一般的に、このようなコードは複雑な計算やデータ処理のようなタスクを実行するため、QML よりも C++ の方が高速です。
Qt では、QML と C++ のコードをアプリケーションに統合するための様々なアプローチを提供しています。典型的なユースケースは、ユーザーインターフェースにデータのリストを表示することです。データセットが静的で、単純で、かつ/または小さい場合、QMLで書かれたモデルで十分です。
以下のスニペットはQMLで書かれたモデルの例を示しています:
model: [ "Item 1", "Item 2", "Item 3" ] model: 10
大規模であったり、頻繁に変更されるような動的なデータセットにはC++を使用してください。
C++からQMLへのデータ公開
QMLのリファクタリングはC++のリファクタリングよりもずっと簡単なので、メンテナンスの手間を省くためには、C++の型をできるだけQMLに意識させないようにする必要があります。これは、C++の型への参照をQMLに「プッシュ」することで実現できます。
そのためには、必須プロパティを使用し、QQmlApplicationEngine::setInitialProperties で設定します。また、C++側がQMLに提供したいすべてのデータを返すsingletons を1つまたは複数作成することも可能です。
この方法では、将来QMLのリファクタリングが必要になってもC++は変更されません。
C++の型をQMLに公開する正しい方法を選択するためのクイックガイドについては、C++とQMLの正しい統合方法を選択するを参照してください。
関連情報
チュートリアルではQt Design Studio
Qt Design Studio では、.ui.qml という拡張子を持つ UI ファイルを使用して、UI の視覚的な部分と、.qmlファイルで実装する UI ロジックを分離しています。UIファイルの編集は、 の ビューでのみ行ってください。 がサポートしていないコードを他のツールで追加すると、エラーメッセージが表示されます。エラーを修正して、UIファイルの視覚的な編集を可能にしてください。通常、サポートされていないコードはQt Design Studio 2D Qt Design Studio .qmlファイルに移動する必要があります。
関連情報
Qt Quick ビューの使用
モデルに状態を保存する
Avoid Storing State in Delegates を参照。
Qt Quick レイアウトの使用
Qt では、Qt Quick アイテムを視覚的にレイアウトするためのQt Quick レイアウトを提供しています。その代替であるアイテムのポジショナーとは異なり、Qt Quick レイアウトは、ウィンドウのサイズ変更時にその子のサイズを変更することもできます。多くの場合、Qt Quick レイアウトは望ましい選択ですが、使用する際には以下の注意 点を考慮する必要があります:
注意点
- anchors 、またはwidth 、height プロパティを使用して、レイアウト以外の親アイテムに対するレイアウトのサイズを指定します。
- Layout attachedプロパティを使用して、レイアウトの直接の子のサイズと配置属性を設定する。
注意点
- implicitWidthとimplicitHeightを提供するアイテムには、その暗黙のサイズが満足できない場合を除き、優先サイズを定義しないでください。
- レイアウトの直属の子であるアイテムにアンカーを使わない。代わりに
Layout.preferredWidth
とLayout.preferredHeight
を使用してください:RowLayout { id: layout anchors.fill: parent spacing: 6 Rectangle { color: 'orange' Layout.fillWidth: true Layout.minimumWidth: 50 Layout.preferredWidth: 100 Layout.maximumWidth: 300 Layout.minimumHeight: 150 Text { anchors.centerIn: parent text: parent.width + 'x' + parent.height } } Rectangle { color: 'plum' Layout.fillWidth: true Layout.minimumWidth: 100 Layout.preferredWidth: 200 Layout.preferredHeight: 100 Text { anchors.centerIn: parent text: parent.width + 'x' + parent.height } } }
Note: レイアウトとアンカーは、どちらもメモリとインスタンス生成に時間がかかるタイプのオブジェクトです。x、y、width、heightプロパティへの単純なバインディングで十分な場合は、(特にリストやテーブルのデリゲート、コントロールのスタイルでは)使用を避けてください。
関連情報
型の安全性
QMLでプロパティを宣言する場合、"var "型を使うのが簡単で便利です:
property var name property var size property var optionsMenu
しかし、この方法にはいくつかの欠点があります:
- 間違った型の値が代入された場合、報告されるエラーはプロパティが代入された場所ではなく、プロパティ宣言の場所を指すことになります。このため、エラーを追跡することが難しくなり、開発プロセスが遅くなります。
- 上記のようなエラーを発見するための静的解析は不可能です。
- プロパティの実際の基本型は、読み手にとって必ずしもすぐに明確になるとは限りません。
代わりに、可能な限り常に実際の型を使用します:
property string name
property int size
property MyMenu optionsMenu
パフォーマンス
QMLやQt Quick のパフォーマンスに関する情報はQML Performance Considerations And Suggestions を参照してください。
宣言的なバインディングを優先する
QMLでは、入力イベントへの応答やネットワーク経由でのデータ送信などのタスクを、 命令型のJavaScriptコードで実行することが可能です。QMLにおいて命令型コードは重要な位置を占めますが、同時に、どのような場合に 命令型コードを使用しないかを意識することも重要です。
例えば、次のような命令的な代入を考えてみましょう:
Rectangle { Component.onCompleted: color = "red" }
これには次のような欠点があります:
- 遅い。colorプロパティは、まずデフォルトの値で評価され、後でもう一度 "red "で評価されます。
- ビルド時に発見される可能性のあるエラーを実行時に遅らせ、開発プロセスを遅くする。
- 宣言的バインディングを上書きしてしまう。ほとんどの場合、これは意図的なものですが、意図しない場合もあります。詳しくはバインディングの上書きのデバッグを参照してください。
- 例えば、Qt Quick DesignerはJavaScriptをサポートしていません。
代わりに宣言型バインディングに書き換えることができます:
Rectangle {
color: "red"
}
デリゲートにステートを保存しない
デリゲートに状態を保存しない。ここで問題になるのは、デリゲートが何度も生成・破棄されるため、保存された状態が失われてしまうことだ。
// Wrong approach: ListView { // ... delegate: Button { // ... property bool someStateProperty onClicked: someStateProperty = true } }
その代わりに、デリゲートの外に状態を保存する。例えば、モデルの中に。デリゲートが破棄されても、保存された状態は失われません。
// Right approach: ListView { // ... delegate: Button { // ... onClicked: model.someStateProperty = true } }
ユーザー向けの文字列を翻訳可能にする
ユーザー向けの文字列は最初から翻訳可能にしておくことをお勧めします。翻訳のためのソースコードの書き方を参照してください。
ToolButton { id: selectionToolButton // ... icon.source: "qrc:/images/selection.png" Tooltip.Text: qsTr("Select pixels within an area and move them") onClicked: canvas.tool = ImageCanvas.SelectionTool }
ネイティブスタイルをカスタマイズしない
ネイティブスタイル(WindowsとmacOSのスタイル)はカスタマイズをサポートしていません。ネイティブスタイルをカスタマイズしないようにしてください。
// Wrong approach: import QtQuick.Controls.Windows // Don't customize a native style Button { background: Rectangle { /*...*/ } }
その代わりに、カスタマイズしたコントロールは、すべてのプラットフォームで利用可能な単一のスタイル(Basic Style、Fusion Style、Imagine Style、Material Style、Universal Styleなど)をベースにすることをお勧めします。そうすることで、アプリケーションがどのスタイルで実行されても、常に同じように見えることが保証されます。別のスタイルを使用する方法については、 Qt Quick Controls でスタイルを使用する を参照してください。また、独自のスタイルを作成することもできます。
// Right approach: import QtQuick.Controls.Basic // You can customize a commonly available style Button { background: Rectangle { /*...*/ } }
ツールとユーティリティ
QML やQt Quick をより簡単に操作するための便利なツールやユーティリティについては、Qt Quick Tools and Utilities を参照してください。
シーングラフ
Qt Quick のシーングラフについては、Qt Quick Scene Graph を参照してください。
スケーラブルなユーザーインターフェース
ディスプレイの解像度が向上するにつれて、スケーラブルなアプリケーションUIはますます重要になります。これを実現するアプローチの1つは、異なるスクリーン解像度のためにUIの複数のコピーを保持し、利用可能な解像度に応じて適切なものをロードすることです。これはかなりうまくいきますが、メンテナンスのオーバーヘッドが増えます。
Qtはこの問題に対してより良い解決策を提供しており、アプリケーション開発者は以下のヒントに従うことを推奨します:
- ビジュアルアイテムのレイアウトには、アンカーまたはQt Quick Layouts モジュールを使用します。
- ビジュアルアイテムの幅と高さを明示的に指定しない。
- 画像やアイコンのようなUIリソースを、アプリケーションがサポートするディスプレイ解像度ごとに提供する。Qt Quick Controls ギャラリーの例では、
@2x
、@3x
、@4x
の解像度に対応したqt-logo.png
を提供することで、高解像度ディスプレイにも対応できるようにしています。Qtは、高DPIスケーリング機能が明示的に有効になっていれば、指定されたディスプレイに適した画像を自動的に選択します。 - 小さなアイコンには SVG 画像を使用します。大きな SVG はレンダリングに時間がかかりますが、小さな SVG はうまく機能します。ベクター画像は、ビットマップ画像で必要なように、複数のバージョンの画像を提供する必要性を回避します。
- Font Awesomeなどのフォントベースのアイコンを使いましょう。これらのアイコンはどんなディスプレイ解像度にも対応し、カラー化も可能です。Qt Quick Controls Text Editorの例がこれをよく示しています。
このようにすれば、アプリケーションのUIはディスプレイの解像度に応じて拡大縮小されるはずです。
関連情報
© 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.