カスタマイズQt Quick Controls
Qt Quick Controls はアイテムの階層(ツリー)で構成されています。カスタムのルック&フィールを提供するために、各項目のデフォルトの QML 実装をカスタムのものに置き換えることができます。
コントロールのカスタマイズ
UIの特定の部分だけ "その場限り "のルックを作成し、他の部分には完全なスタイルを使用したい場合があります。今使っているスタイルには満足しているけれど、何か特別な意味を持つボタンがあるとします。
このボタンを作成する最初の方法は、必要な場所にインプレースで定義することです。たとえば、「基本」スタイルの「ボタン」の角が四角いことに不満があるとします。角を丸くするには、background アイテムをオーバーライドして、Rectangle の半径プロパティを設定します:
import QtQuick import QtQuick.Controls.Basic ApplicationWindow { width: 400 height: 400 visible: true Button { id: button text: "A Special Button" background: Rectangle { implicitWidth: 100 implicitHeight: 40 color: button.down ? "#d6d6d6" : "#f6f6f6" border.color: "#26282a" border.width: 1 radius: 4 } } }
注意: どのスタイルでも、コントロールを構成するさまざまなアイテムは一緒に動作するように設計されているため、目的の外観を得るには他のアイテムをオーバーライドする必要がある場合があります。また、すべてのスタイルをカスタマイズできるわけではありません。詳細については、「カスタマイズ・リファレンス」の注記を参照してください。
ボタンを作成する2つ目の方法は、丸みを帯びたボタンを複数の場所で使用する場合に適しています。この方法では、コードをプロジェクト内のQMLファイルに移動します。
この方法では、BasicスタイルのButton.qml
から背景のコードをコピーします。このファイルは、Qtインストール内の以下のパスにあります:
$QTDIR/qml/QtQuick/Controls/Basic/Button.qml
その後、次の行を追加します:
radius: 4
モジュール自体のコントロールとの混同を避けるため、このファイルをMyButton.qml
と呼ぶことにします。アプリケーションでコントロールを使用するには、ファイル名で参照してください:
import QtQuick.Controls.Basic ApplicationWindow { MyButton { text: qsTr("A Special Button") } }
ボタンを作成する3つ目の方法は、ファイルがファイルシステムのどこにあるかという点でも、QMLでどのように使われるかという点でも、もう少し構造化されています。まず、上と同じように既存のファイルをコピーします。ただし、今回はプロジェクトのサブフォルダに(例えば)controls
という名前で入れます。コントロールを使用するには、まずそのフォルダをネームスペースにインポートします:
import QtQuick.Controls.Basic import "controls" as MyControls ApplicationWindow { MyControls.Button { text: qsTr("A Special Button") } }
これでMyControls
ネームスペースができたので、Qt Quick Controls モジュールの実際の対応するものにちなんでコントロールに名前を付けることができます。追加したいコントロールがあれば、このプロセスを繰り返すことができます。
これら3つの方法の利点は、テンプレートをゼロから実装する必要がないことです。
注: ToolTip は内部的に作成された共有アイテムであるため、ここで紹介した3つのアプローチは、添付の をカスタマイズする場合には機能しません。ToolTip
を単発でカスタマイズするには、Custom Tool Tips を参照してください。添付のToolTip
をカスタマイズするには、独自のスタイルの一部として提供する必要があります。
カスタム・スタイルの作成
独自のスタイルを作成するには、いくつかの方法があります。以下では、様々なアプローチについて説明します。
スタイルの定義
Qt Quick Controls では、スタイルとは基本的に1つのディレクトリ内にあるQMLファイルの集合を指します。スタイルが使用可能であるためには、4つの要件があります:
- コントロール(例えば、
Button.qml
)と名前が一致するQMLファイルが少なくとも1つ存在すること。 - 各 QML ファイルは、QtQuick.Templatesインポートにある関連する型をルート項目として含んでいなければなりません。例えば、Button.qml は、Button テンプレートをルート項目として含んでいなければなりません。
前のセクションで行ったように、QtQuick.Controlsインポートから対応する型を使用した場合、うまくいきません。
- qmldirファイルは QML ファイルと一緒に存在しなければなりません。以下は、ボタンを提供するスタイルのシンプルな
qmldir
ファイルの例です:module MyStyle Button 2.15 Button.qml
コンパイル時のスタイル選択を使用している場合、qmldirはフォールバックスタイルもインポートする必要があります:
# ... import QtQuick.Controls.Basic auto
これは、例えば、QQuickStyle::setFallbackStyle()を使用する代わりに、実行時のスタイル選択のために行うこともできます。
このようなスタイルのディレクトリ構造は次のようになります:
MyStyle ├─── Button.qml └─── qmldir
- ファイルはQMLインポートパスで検索可能なディレクトリに置く必要があります。
例えば、上記のMyStyleディレクトリへのパスが
/home/user/MyApp/MyStyle
であった場合、/home/user/MyApp
をQMLインポートパスに追加する必要があります。MyAppで MyStyleを 使用するには、MyStyleを名前で参照します:
./MyApp -style MyStyle
mystyleまたはMYSTYLEを渡すことはサポートされていません。
mystyleまたはMYSTYLEを渡すことはサポートされていません。デフォルトでは、スタイリングシステムは、実装されていないコントロールのフォールバックとしてBasicスタイルを使用します。その他の組み込みスタイルをカスタマイズまたは拡張するには、QQuickStyle を使用して別のフォールバック・スタイルを指定することができます。
これが意味するのは、カスタム・スタイルのために好きなだけコントロールを実装し、ほとんどどこにでも配置できるということです。また、ユーザーがアプリケーション用に独自のスタイルを作成することもできます。
Qt Quick Designer でのカスタムスタイルのプレビュー
上記の方法を使用して、Qt Quick Designer でカスタム スタイルをプレビューできます。そのためには、プロジェクトにqtquickcontrols2.confファイルがあり、以下のエントリが存在することを確認してください:
[Controls] Style=MyStyle
詳細については、フラットスタイルの例を参照してください。
スタイル固有のC++拡張
C++を使用してカスタムスタイルを拡張する必要がある場合があります。
- もしその型を使用するスタイルがアプリケーションで使用される唯一のスタイルである場合は、QML_ELEMENT マクロを追加し、そのファイルをQMLモジュールの一部とすることで、QMLエンジンにその型を登録します:
qmake#tab-qmakeヘッダーでクラスが宣言されている場合、そのクラスはQMLエンジンに登録されます。qt_add_qml_module(ACoolItem URI MyItems VERSION 1.0 SOURCES acoolcppitem.cpp acoolcppitem.h )
CONFIG += qmltypes QML_IMPORT_NAME = MyItems QML_IMPORT_MAJOR_VERSION = 1
クラスが宣言されているヘッダがプロジェクトのインクルードパスからアクセスできない場合、生成された登録コードをコンパイルできるようにインクルードパスを修正する必要があるかもしれません。
INCLUDEPATH += MyItems
詳しくはC++からのQML型の定義と QMLアプリケーションのビルドを参照してください。
- 型を使用するスタイルがアプリケーションで使用される多くのスタイルのうちの1つである場合、各スタイルを別々のモジュールに入れることを検討してください。モジュールは必要に応じてロードされます。
カスタムスタイルの考慮事項
独自のスタイルを実装してコントロールをカスタマイズする場合、アプリケーションのパフォーマンスを可能な限り向上させるために注意すべき点がいくつかあります。
スタイルのアイテム デリゲートの実装に id を割り当てないようにする。
スタイルの定義で説明したように、コントロールに独自のスタイルを実装する場合、そのコントロールに関連するテンプレートから始めます。例えば、スタイルのButton.qml
は、このような構造になっています:
T.Button { // ... background: Rectangle { // ... } contentItem: Text { // ... } // ... }
アプリケーションで Button を使用する場合、background
とcontentItem
アイテムが作成され、ルートButton
アイテムの親になります:
// Creates the Button root item, the Rectangle background, // and the Text contentItem. Button { text: qsTr("Confirm") }
アプリケーションでButtonを使用する場合、、 のアイテムが作成され、ルート アイテムの親となります。(コントロールのカスタマイズで説明したように)Buttonを単発でカスタマイズする必要があるとします:
import QtQuick import QtQuick.Controls.Basic ApplicationWindow { width: 400 height: 400 visible: true Button { id: button text: "A Special Button" background: Rectangle { implicitWidth: 100 implicitHeight: 40 color: button.down ? "#d6d6d6" : "#f6f6f6" border.color: "#26282a" border.width: 1 radius: 4 } } }
QMLでは、通常、この場合、デフォルトのbackground
実装と、単発のカスタムbackground
アイテムの両方が作成されることになります。Qt Quick Controls では、両方のアイテムの作成を避け、カスタムbackground
のみを作成するテクニックを採用しており、コントロールの作成パフォーマンスを大幅に向上させています。
このテクニックは、そのアイテムのスタイルの実装にid がないことに依存します。id が割り当てられると、このテクニックは機能せず、両方のアイテムが作成されます。たとえば、ファイル内の他のオブジェクトがこれらのアイテムを参照できるように、background
やcontentItem
に id を割り当てたくなることがあります:
T.Button { // ... background: Rectangle { id: backgroundRect // ... } contentItem: Text { // Use backgroundRect in some way... } // ... }
このコードでは、カスタマイズされた背景を持つButtonインスタンスが作成されるたびに、両方の背景が作成されることになり、最適な作成パフォーマンスが得られません。
Qt 5.15以前では、古い未使用の背景を削除して、関連するリソースを解放していました。しかし、コントロールはアイテムを所有していないので、削除すべきではありません。Qt 5.15では、古いアイテムは削除されなくなりました。そのため、backgroundRect
のアイテムは必要以上に長く、通常はアプリケーションが終了するまで生き続けることになります。古いアイテムは非表示になり、コントロールから視覚的にアンペアレントされ、アクセシビリティツリーから削除されますが、このコンテキストでidを割り当てるときは、これらの未使用アイテムの作成時間とメモリ使用量を念頭に置くことが重要です。
カスタムアイテムの命令的な割り当ては避ける
上のセクションで述べたテクニックは、アイテムが宣言的に初めて割り当てられる場合にのみ機能します。可能であれば、カスタムアイテムの割り当てには常に宣言的バインディングを使用してください。
QMLの実装でQtQuick.Controlsをインポートしない
スタイルのコントロール実装の QML を書く際には、QtQuick.Controls
をインポートしないことが重要です。インポートすると、QMLコンパイラでコンパイルできなくなります。
他の型が使用する型を実装する
アプリケーションでScrollViewを使用していて、そのスクロールバーをカスタマイズしたいと思ったとします。ScrollBar.qmlを実装し、ScrollView がカスタマイズされたScrollBar を自動的にピックアップするようにしたいところです。しかし、これはうまくいきません。ScrollBar.qmlと ScrollView.qml の両方を実装する必要があります。
付属プロパティ
スタイルには、すべてのコントロールに適用される特定のプロパティや属性があるのが普通です。アタッチド・プロパティは、そのアイテムに属する既存のC++を変更することなく、QMLのアイテムを拡張する素晴らしい方法です。例えば、マテリアル・スタイルと ユニバーサル・スタイルには、アイテムやその子アイテムを明るいテーマで表示するか、暗いテーマで表示するかを制御するテーマ・プロパティが付属しています。
例として、高さを制御する付属プロパティを追加してみましょう。このスタイルでは、高度をドロップシャドウで表現します。高度が高いほど、シャドウは大きくなります。
最初のステップは、Qt Creator で新しいQt Quick Controls アプリケーションを作成することです。その後、標高を格納するC++型を追加します。この型は、スタイルでサポートされるすべてのコントロールに使用され、後で他のプロパティを追加する可能性があるため、MyStyleと呼ぶことにします。以下はMyStyle.h
です:
#ifndef MYSTYLE_H #define MYSTYLE_H #include <QObject> #include <QtQml> class MyStyle : public QObject { Q_OBJECT Q_PROPERTY(int elevation READ elevation WRITE setElevation NOTIFY elevationChanged) public: explicit MyStyle(QObject *parent = nullptr); static MyStyle *qmlAttachedProperties(QObject *object); int elevation() const; void setElevation(int elevation); signals: void elevationChanged(); private: int m_elevation; }; QML_DECLARE_TYPEINFO(MyStyle, QML_HAS_ATTACHED_PROPERTIES) #endif // MYSTYLE_H
MyStyle.cpp
:
#include "mystyle.h" MyStyle::MyStyle(QObject *parent) : QObject(parent), m_elevation(0) { } MyStyle *MyStyle::qmlAttachedProperties(QObject *object) { return new MyStyle(object); } int MyStyle::elevation() const { return m_elevation; } void MyStyle::setElevation(int elevation) { if (elevation == m_elevation) return; m_elevation = elevation; emit elevationChanged(); }
MyStyle
タイプは、インスタンス化されるのではなく、アタッチされたプロパティに使用されるという意味で特別です。そのため、次のようにmain.cpp
に登録します:
#include <QGuiApplication> #include <QQmlApplicationEngine> #include "mystyle.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); qmlRegisterUncreatableType<MyStyle>("MyStyle", 1, 0, "MyStyle", "MyStyle is an attached property"); QQmlApplicationEngine engine; // Make the directory containing our style known to the QML engine. engine.addImportPath(":/"); engine.load(QUrl(QLatin1String("qrc:/main.qml"))); return app.exec(); }
次に、$QTDIR/qml/QtQuick/Controls/Basic/
のBasicスタイルからButton.qml
をプロジェクト・ディレクトリの新しいmyproject
フォルダにコピーします。新しくコピーしたButton.qml
を、QMLファイルを含むリソースファイルであるqml.qrc
に追加します。
次に、Buttonのbackground デリゲートにドロップシャドウを追加します:
// ... import QtQuick.Effects import MyStyle // ... background: Rectangle { // ... layer.enabled: control.enabled && control.MyStyle.elevation > 0 layer.effect: MultiEffect { shadowEnabled: true shadowHorizontalOffset: 3 shadowVerticalOffset: 3 shadowColor: control.visualFocus ? "#330066ff" : "#aaaaaa" shadowBlur: control.pressed ? 0.8 : 0.4 } }
ここで注意してください:
- 標高が高いときは、わざわざドロップシャドウを使う必要はありません。
0
- ボタンにフォーカスがあるかどうかで、影の色を変える。
- 影の大きさを標高に依存させる。
付属のプロパティを試すために、main.qml
に2つのボタンがあるRow を作成します:
import QtQuick import QtQuick.Controls import MyStyle 1.0 ApplicationWindow { id: window width: 400 height: 400 visible: true Row { spacing: 20 anchors.centerIn: parent Button { text: "Button 1" } Button { text: "Button 2" MyStyle.elevation: 10 } } }
1つのボタンは標高がなく、もう1つのボタンは標高が10
です。
これでサンプルを実行できます。アプリケーションに新しいスタイルを使用するように指示するために、アプリケーションの引数として-style MyStyle
を渡しますが、使用するスタイルを指定する方法はたくさんあります。
最終結果です:
MyStyle
に属するアタッチされたプロパティを使用しているため、import MyStyle 1.0
ステートメントが必要なだけであることに注意してください。インポートを削除しても、両方のボタンでカスタム・スタイルが使用されます。
カスタマイズのリファレンス
以下のスニペットは、「コントロールのカスタマイズ」セクションと同じアプローチで基本スタイルのコントロールをカスタマイズした例です。このコードは、カスタムのルック&フィールを実装するための出発点として使用できます。
注意: macOSと Windowsのスタイルはカスタマイズに適していません。基本スタイル、フュージョン・スタイル、イマジン・スタイル、マテリアル・スタイル、ユニバーサル・スタイルなど、すべてのプラットフォームで利用可能な単一のスタイルをベースにカスタマイズすることをお勧めします。そうすることで、アプリケーションがどのスタイルで実行されても、常に同じように見えることが保証されます。別のスタイルを使用する方法については、 Qt Quick Controls でスタイルを使用する を参照してください。また、独自のスタイルを作成することもできます。
ApplicationWindow のカスタマイズ
ApplicationWindow は1つのビジュアル・アイテムから構成されています: 。background
import QtQuick import QtQuick.Controls.Basic ApplicationWindow { visible: true background: Rectangle { gradient: Gradient { GradientStop { position: 0; color: "#ffffff" } GradientStop { position: 1; color: "#c1bbf9" } } } }
BusyIndicator のカスタマイズ
BusyIndicator のカスタマイズは 2 つのビジュアルアイテム と で構成されています。background contentItem
import QtQuick import QtQuick.Controls.Basic BusyIndicator { id: control contentItem: Item { implicitWidth: 64 implicitHeight: 64 Item { id: item x: parent.width / 2 - 32 y: parent.height / 2 - 32 width: 64 height: 64 opacity: control.running ? 1 : 0 Behavior on opacity { OpacityAnimator { duration: 250 } } RotationAnimator { target: item running: control.visible && control.running from: 0 to: 360 loops: Animation.Infinite duration: 1250 } Repeater { id: repeater model: 6 Rectangle { id: delegate x: item.width / 2 - width / 2 y: item.height / 2 - height / 2 implicitWidth: 10 implicitHeight: 10 radius: 5 color: "#21be2b" required property int index transform: [ Translate { y: -Math.min(item.width, item.height) * 0.5 + 5 }, Rotation { angle: delegate.index / repeater.count * 360 origin.x: 5 origin.y: 5 } ] } } } } }
ボタンのカスタマイズ
ボタンはbackground とcontent item の2つのビジュアルアイテムから構成されています。
import QtQuick import QtQuick.Controls.Basic Button { id: control text: qsTr("Button") contentItem: Text { text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: control.down ? "#17a81a" : "#21be2b" horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { implicitWidth: 100 implicitHeight: 40 opacity: enabled ? 1 : 0.3 border.color: control.down ? "#17a81a" : "#21be2b" border.width: 1 radius: 2 } }
チェックボックスのカスタマイズ
CheckBox は3つのビジュアル・アイテムで構成されています: と 。background contentItem indicator
import QtQuick import QtQuick.Controls.Basic CheckBox { id: control text: qsTr("CheckBox") checked: true indicator: Rectangle { implicitWidth: 26 implicitHeight: 26 x: control.leftPadding y: parent.height / 2 - height / 2 radius: 3 border.color: control.down ? "#17a81a" : "#21be2b" Rectangle { width: 14 height: 14 x: 6 y: 6 radius: 2 color: control.down ? "#17a81a" : "#21be2b" visible: control.checked } } contentItem: Text { text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: control.down ? "#17a81a" : "#21be2b" verticalAlignment: Text.AlignVCenter leftPadding: control.indicator.width + control.spacing } }
CheckDelegateのカスタマイズ
CheckDelegate には3つの視覚的な項目があります: と 。background contentItem indicator
import QtQuick import QtQuick.Controls.Basic CheckDelegate { id: control text: qsTr("CheckDelegate") checked: true contentItem: Text { rightPadding: control.indicator.width + control.spacing text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: control.down ? "#17a81a" : "#21be2b" elide: Text.ElideRight verticalAlignment: Text.AlignVCenter } indicator: Rectangle { implicitWidth: 26 implicitHeight: 26 x: control.width - width - control.rightPadding y: control.topPadding + control.availableHeight / 2 - height / 2 radius: 3 color: "transparent" border.color: control.down ? "#17a81a" : "#21be2b" Rectangle { width: 14 height: 14 x: 6 y: 6 radius: 2 color: control.down ? "#17a81a" : "#21be2b" visible: control.checked } } background: Rectangle { implicitWidth: 100 implicitHeight: 40 visible: control.down || control.highlighted color: control.down ? "#bdbebf" : "#eeeeee" } }
コンボボックスのカスタマイズ
ComboBox は , , , , で構成されています。background content item popup indicator delegate
pragma ComponentBehavior: Bound import QtQuick import QtQuick.Controls.Basic ComboBox { id: control model: ["First", "Second", "Third"] delegate: ItemDelegate { id: delegate required property var model required property int index width: control.width contentItem: Text { text: delegate.model[control.textRole] color: "#21be2b" font: control.font elide: Text.ElideRight verticalAlignment: Text.AlignVCenter } highlighted: control.highlightedIndex === index } indicator: Canvas { id: canvas x: control.width - width - control.rightPadding y: control.topPadding + (control.availableHeight - height) / 2 width: 12 height: 8 contextType: "2d" Connections { target: control function onPressedChanged() { canvas.requestPaint(); } } onPaint: { context.reset(); context.moveTo(0, 0); context.lineTo(width, 0); context.lineTo(width / 2, height); context.closePath(); context.fillStyle = control.pressed ? "#17a81a" : "#21be2b"; context.fill(); } } contentItem: Text { leftPadding: 0 rightPadding: control.indicator.width + control.spacing text: control.displayText font: control.font color: control.pressed ? "#17a81a" : "#21be2b" verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { implicitWidth: 120 implicitHeight: 40 border.color: control.pressed ? "#17a81a" : "#21be2b" border.width: control.visualFocus ? 2 : 1 radius: 2 } popup: Popup { y: control.height - 1 width: control.width height: Math.min(contentItem.implicitHeight, control.Window.height - topMargin - bottomMargin) padding: 1 contentItem: ListView { clip: true implicitHeight: contentHeight model: control.popup.visible ? control.delegateModel : null currentIndex: control.highlightedIndex ScrollIndicator.vertical: ScrollIndicator { } } background: Rectangle { border.color: "#21be2b" radius: 2 } } }
ComboBox Model Roles で説明したように、ComboBox は複数のタイプのモデルをサポートしています。
すべてのモデルは modelData
で匿名プロパティを提供するので、以下の式はすべてのケースで正しいテキストを取得します:
text: model[control.textRole]
特定のtextRole
、選択された役割を提供する構造化データを持つモデルを提供する場合、この式は通常のプロパティ検索です。文字列のリストのような特異なデータを持つモデルと空のtextRole
を提供する場合、この式はmodelData
を検索します。
DelayButtonのカスタマイズ
DelayButton は、 と の2つのビジュアル・アイテムから構成されています。background content item
import QtQuick import QtQuick.Controls.Basic DelayButton { id: control checked: true text: qsTr("Delay\nButton") contentItem: Text { text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: "white" horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { implicitWidth: 100 implicitHeight: 100 opacity: enabled ? 1 : 0.3 color: control.down ? "#17a81a" : "#21be2b" radius: size / 2 readonly property real size: Math.min(control.width, control.height) width: size height: size anchors.centerIn: parent Canvas { id: canvas anchors.fill: parent Connections { target: control function onProgressChanged() { canvas.requestPaint(); } } onPaint: { var ctx = getContext("2d") ctx.clearRect(0, 0, width, height) ctx.strokeStyle = "white" ctx.lineWidth = parent.size / 20 ctx.beginPath() var startAngle = Math.PI / 5 * 3 var endAngle = startAngle + control.progress * Math.PI / 5 * 9 ctx.arc(width / 2, height / 2, width / 2 - ctx.lineWidth / 2 - 2, startAngle, endAngle) ctx.stroke() } } } }
ダイヤルのカスタマイズ
ダイヤルは、background とhandle の2つのビジュアルアイテムで構成されています。
インポート QtQuickインポート QtQuick.Controls.BasicDial{id:control background:長方形{x:control.width / 2 - width / 2 y:control.height / 2 - height / 2 implicitWidth:140 implicitHeight:140 width:Math.max(64,Math.min(control.width,control.height))height:width color:"transparent" radius:width / 2 border.color:control.pressed?"#17a81a":"#21be2b" opacity:control.enabled?1:0.3}handle:矩形{id:handleItemx: control.background.x + control.background.width / 2 - width / 2y: control.background.y + control.background.height / 2 - height / 2 width:16 height:16 color:control.pressed?"#17a81a":"#21be2b" radius:8 アンチエイリアス:true opacity:control.enabled?1:0.3 transform:[ Translate{y:-Math.min(control.background.width,control.background.height)* 0.4 + handleItem.height / 2}、 Rotation{angle:control.angle origin.x:handleItem.width / 2 origin.y:handleItem.height / 2} } }
引き出しのカスタマイズ
ドロワーは、ビジュアルbackground アイテムを持つことができます。
background: Rectangle { Rectangle { x: parent.width - 1 width: 1 height: parent.height color: "#21be2b" } }
フレームのカスタマイズ
フレームは1つのビジュアルアイテムで構成されます:background 。
import QtQuick import QtQuick.Controls.Basic Frame { background: Rectangle { color: "transparent" border.color: "#21be2b" radius: 2 } Label { text: qsTr("Content goes here!") } }
グループボックスのカスタマイズ
GroupBox は、 と の2つのビジュアル・アイテムで構成されます。background label
import QtQuick import QtQuick.Controls.Basic GroupBox { id: control title: qsTr("GroupBox") background: Rectangle { y: control.topPadding - control.bottomPadding width: parent.width height: parent.height - control.topPadding + control.bottomPadding color: "transparent" border.color: "#21be2b" radius: 2 } label: Label { x: control.leftPadding width: control.availableWidth text: control.title color: "#21be2b" elide: Text.ElideRight } Label { text: qsTr("Content goes here!") } }
ItemDelegateのカスタマイズ
ItemDelegate は、 と の2つのビジュアル・アイテムから構成されています。background content item
import QtQuick import QtQuick.Controls.Basic ItemDelegate { id: control text: qsTr("ItemDelegate") contentItem: Text { rightPadding: control.spacing text: control.text font: control.font color: control.enabled ? (control.down ? "#17a81a" : "#21be2b") : "#bdbebf" elide: Text.ElideRight verticalAlignment: Text.AlignVCenter } background: Rectangle { implicitWidth: 100 implicitHeight: 40 opacity: enabled ? 1 : 0.3 color: control.down ? "#dddedf" : "#eeeeee" Rectangle { width: parent.width height: 1 color: control.down ? "#17a81a" : "#21be2b" anchors.bottom: parent.bottom } } }
ラベルのカスタマイズ
ラベルはビジュアル項目background を持つことができます。
import QtQuick import QtQuick.Controls.Basic Label { text: qsTr("Label") color: "#21be2b" }
メニューのカスタマイズ
- Menu はビジュアル項目( )で構成されています。background
- MenuItem は4つのビジュアル・アイテムから構成されています: 、 、 。background content item indicator arrow
- MenuSeparator は、ビジュアルな と で構成されています。background content item
import QtQuick import QtQuick.Controls.Basic Menu { id: menu Action { text: qsTr("Tool Bar"); checkable: true } Action { text: qsTr("Side Bar"); checkable: true; checked: true } Action { text: qsTr("Status Bar"); checkable: true; checked: true } MenuSeparator { contentItem: Rectangle { implicitWidth: 200 implicitHeight: 1 color: "#21be2b" } } Menu { title: qsTr("Advanced") // ... } topPadding: 2 bottomPadding: 2 delegate: MenuItem { id: menuItem implicitWidth: 200 implicitHeight: 40 arrow: Canvas { x: parent.width - width implicitWidth: 40 implicitHeight: 40 visible: menuItem.subMenu onPaint: { var ctx = getContext("2d") ctx.fillStyle = menuItem.highlighted ? "#ffffff" : "#21be2b" ctx.moveTo(15, 15) ctx.lineTo(width - 15, height / 2) ctx.lineTo(15, height - 15) ctx.closePath() ctx.fill() } } indicator: Item { implicitWidth: 40 implicitHeight: 40 Rectangle { width: 26 height: 26 anchors.centerIn: parent visible: menuItem.checkable border.color: "#21be2b" radius: 3 Rectangle { width: 14 height: 14 anchors.centerIn: parent visible: menuItem.checked color: "#21be2b" radius: 2 } } } contentItem: Text { leftPadding: menuItem.indicator.width rightPadding: menuItem.arrow.width text: menuItem.text font: menuItem.font opacity: enabled ? 1.0 : 0.3 color: menuItem.highlighted ? "#ffffff" : "#21be2b" horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { implicitWidth: 200 implicitHeight: 40 opacity: enabled ? 1 : 0.3 color: menuItem.highlighted ? "#21be2b" : "transparent" } } background: Rectangle { implicitWidth: 200 implicitHeight: 40 color: "#ffffff" border.color: "#21be2b" radius: 2 } }
メニューバーのカスタマイズ
MenuBar にはビジュアルな アイテムがあり、 は と の2つのビジュアル・アイテムで構成されています。background MenuBarItem background content item
import QtQuick import QtQuick.Controls.Basic MenuBar { id: menuBar Menu { title: qsTr("File") } Menu { title: qsTr("Edit") } Menu { title: qsTr("View") } Menu { title: qsTr("Help") } delegate: MenuBarItem { id: menuBarItem contentItem: Text { text: menuBarItem.text font: menuBarItem.font opacity: enabled ? 1.0 : 0.3 color: menuBarItem.highlighted ? "#ffffff" : "#21be2b" horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { implicitWidth: 40 implicitHeight: 40 opacity: enabled ? 1 : 0.3 color: menuBarItem.highlighted ? "#21be2b" : "transparent" } } background: Rectangle { implicitWidth: 40 implicitHeight: 40 color: "#ffffff" Rectangle { color: "#21be2b" width: parent.width height: 1 anchors.bottom: parent.bottom } } }
PageIndicatorのカスタマイズ
PageIndicator は、 、 、 で構成されています。background content item delegate
import QtQuick import QtQuick.Controls.Basic PageIndicator { id: control count: 5 currentIndex: 2 delegate: Rectangle { implicitWidth: 8 implicitHeight: 8 radius: width / 2 color: "#21be2b" opacity: index === control.currentIndex ? 0.95 : pressed ? 0.7 : 0.45 required property int index Behavior on opacity { OpacityAnimator { duration: 100 } } } }
ペインのカスタマイズ
ペインはbackground で構成されている。
import QtQuick import QtQuick.Controls.Basic Pane { background: Rectangle { color: "#eeeeee" } Label { text: qsTr("Content goes here!") } }
ポップアップのカスタマイズ
ポップアップはbackground とcontent item で構成される。
import QtQuick import QtQuick.Controls.Basic Popup { id: popup background: Rectangle { implicitWidth: 200 implicitHeight: 200 border.color: "#444" } contentItem: Column {} }
プログレスバーのカスタマイズ
ProgressBar は、 と の2つのビジュアル・アイテムで構成されています。background content item
import QtQuick import QtQuick.Controls.Basic ProgressBar { id: control value: 0.5 padding: 2 background: Rectangle { implicitWidth: 200 implicitHeight: 6 color: "#e6e6e6" radius: 3 } contentItem: Item { implicitWidth: 200 implicitHeight: 4 // Progress indicator for determinate state. Rectangle { width: control.visualPosition * parent.width height: parent.height radius: 2 color: "#17a81a" visible: !control.indeterminate } // Scrolling animation for indeterminate state. Item { anchors.fill: parent visible: control.indeterminate clip: true Row { spacing: 20 Repeater { model: control.width / 40 + 1 Rectangle { color: "#17a81a" width: 20 height: control.height } } XAnimator on x { from: 0 to: -40 loops: Animation.Infinite running: control.indeterminate } } } } }
上記では、indeterminate プログレスバーの状態を表現するために、コンテンツアイテムもアニメーションしています。
ラジオボタンのカスタマイズ
RadioButton は3つのビジュアル・アイテムから構成されています: と 。background content item indicator
import QtQuick import QtQuick.Controls.Basic RadioButton { id: control text: qsTr("RadioButton") checked: true indicator: Rectangle { implicitWidth: 26 implicitHeight: 26 x: control.leftPadding y: parent.height / 2 - height / 2 radius: 13 border.color: control.down ? "#17a81a" : "#21be2b" Rectangle { width: 14 height: 14 x: 6 y: 6 radius: 7 color: control.down ? "#17a81a" : "#21be2b" visible: control.checked } } contentItem: Text { text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: control.down ? "#17a81a" : "#21be2b" verticalAlignment: Text.AlignVCenter leftPadding: control.indicator.width + control.spacing } }
RadioDelegateのカスタマイズ
RadioDelegate は3つのビジュアル・アイテムで構成されています: と 。background contentItem indicator
import QtQuick import QtQuick.Controls.Basic RadioDelegate { id: control text: qsTr("RadioDelegate") checked: true contentItem: Text { rightPadding: control.indicator.width + control.spacing text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: control.down ? "#17a81a" : "#21be2b" elide: Text.ElideRight verticalAlignment: Text.AlignVCenter } indicator: Rectangle { implicitWidth: 26 implicitHeight: 26 x: control.width - width - control.rightPadding y: parent.height / 2 - height / 2 radius: 13 color: "transparent" border.color: control.down ? "#17a81a" : "#21be2b" Rectangle { width: 14 height: 14 x: 6 y: 6 radius: 7 color: control.down ? "#17a81a" : "#21be2b" visible: control.checked } } background: Rectangle { implicitWidth: 100 implicitHeight: 40 visible: control.down || control.highlighted color: control.down ? "#bdbebf" : "#eeeeee" } }
RangeSliderのカスタマイズ
RangeSlider は3つのビジュアル・アイテムから構成されています: と 。background first.handle second.handle
import QtQuick import QtQuick.Controls.Basic RangeSlider { id: control first.value: 0.25 second.value: 0.75 background: Rectangle { x: control.leftPadding y: control.topPadding + control.availableHeight / 2 - height / 2 implicitWidth: 200 implicitHeight: 4 width: control.availableWidth height: implicitHeight radius: 2 color: "#bdbebf" Rectangle { x: control.first.visualPosition * parent.width width: control.second.visualPosition * parent.width - x height: parent.height color: "#21be2b" radius: 2 } } first.handle: Rectangle { x: control.leftPadding + control.first.visualPosition * (control.availableWidth - width) y: control.topPadding + control.availableHeight / 2 - height / 2 implicitWidth: 26 implicitHeight: 26 radius: 13 color: control.first.pressed ? "#f0f0f0" : "#f6f6f6" border.color: "#bdbebf" } second.handle: Rectangle { x: control.leftPadding + control.second.visualPosition * (control.availableWidth - width) y: control.topPadding + control.availableHeight / 2 - height / 2 implicitWidth: 26 implicitHeight: 26 radius: 13 color: control.second.pressed ? "#f0f0f0" : "#f6f6f6" border.color: "#bdbebf" } }
RoundButtonのカスタマイズ
RoundButton もButtonと同様にカスタマイズできます。
スクロールバーのカスタマイズ
ScrollBar は と の2つのビジュアルアイテムから構成されます。background content item
import QtQuick import QtQuick.Controls.Basic ScrollBar { id: control size: 0.3 position: 0.2 active: true orientation: Qt.Vertical contentItem: Rectangle { implicitWidth: 6 implicitHeight: 100 radius: width / 2 color: control.pressed ? "#81e889" : "#c2f4c6" // Hide the ScrollBar when it's not needed. opacity: control.policy === ScrollBar.AlwaysOn || (control.active && control.size < 1.0) ? 0.75 : 0 // Animate the changes in opacity (default duration is 250 ms). Behavior on opacity { NumberAnimation {} } } }
ScrollIndicator
ScrollIndicator は と の 2 つのビジュアルアイテムで構成されます。background content item
import QtQuick import QtQuick.Controls.Basic ScrollIndicator { id: control size: 0.3 position: 0.2 active: true orientation: Qt.Vertical contentItem: Rectangle { implicitWidth: 2 implicitHeight: 100 color: "#c2f4c6" } }
ScrollView のカスタマイズ
ScrollView は、 アイテムと、水平および垂直スクロールバーで構成されます。background
ScrollView { id: control width: 200 height: 200 focus: true Label { text: "ABC" font.pixelSize: 224 } ScrollBar.vertical: ScrollBar { parent: control x: control.mirrored ? 0 : control.width - width y: control.topPadding height: control.availableHeight active: control.ScrollBar.horizontal.active } ScrollBar.horizontal: ScrollBar { parent: control x: control.leftPadding y: control.height - height width: control.availableWidth active: control.ScrollBar.vertical.active } background: Rectangle { border.color: control.activeFocus ? "#21be2b" : "#bdbebf" } }
スライダーのカスタマイズ
スライダーは2つのビジュアルアイテムで構成されます:backgroundとhandle 。
import QtQuick import QtQuick.Controls.Basic Slider { id: control value: 0.5 background: Rectangle { x: control.leftPadding y: control.topPadding + control.availableHeight / 2 - height / 2 implicitWidth: 200 implicitHeight: 4 width: control.availableWidth height: implicitHeight radius: 2 color: "#bdbebf" Rectangle { width: control.visualPosition * parent.width height: parent.height color: "#21be2b" radius: 2 } } handle: Rectangle { x: control.leftPadding + control.visualPosition * (control.availableWidth - width) y: control.topPadding + control.availableHeight / 2 - height / 2 implicitWidth: 26 implicitHeight: 26 radius: 13 color: control.pressed ? "#f0f0f0" : "#f6f6f6" border.color: "#bdbebf" } }
スピンボックスのカスタマイズ
SpinBox は4つのビジュアル・アイテムで構成されています: 、 、 。background contentItem up indicator down indicator
import QtQuick import QtQuick.Controls.Basic SpinBox { id: control value: 50 editable: true contentItem: TextInput { z: 2 text: control.textFromValue(control.value, control.locale) font: control.font color: "#21be2b" selectionColor: "#21be2b" selectedTextColor: "#ffffff" horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter readOnly: !control.editable validator: control.validator inputMethodHints: Qt.ImhFormattedNumbersOnly } up.indicator: Rectangle { x: control.mirrored ? 0 : parent.width - width height: parent.height implicitWidth: 40 implicitHeight: 40 color: control.up.pressed ? "#e4e4e4" : "#f6f6f6" border.color: enabled ? "#21be2b" : "#bdbebf" Text { text: "+" font.pixelSize: control.font.pixelSize * 2 color: "#21be2b" anchors.fill: parent fontSizeMode: Text.Fit horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } } down.indicator: Rectangle { x: control.mirrored ? parent.width - width : 0 height: parent.height implicitWidth: 40 implicitHeight: 40 color: control.down.pressed ? "#e4e4e4" : "#f6f6f6" border.color: enabled ? "#21be2b" : "#bdbebf" Text { text: "-" font.pixelSize: control.font.pixelSize * 2 color: "#21be2b" anchors.fill: parent fontSizeMode: Text.Fit horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } } background: Rectangle { implicitWidth: 140 border.color: "#bdbebf" } }
SplitView のカスタマイズ
SplitView は、 のビジュアルデリゲートから構成されています。handle
SplitView { id: splitView anchors.fill: parent handle: Rectangle { implicitWidth: 4 implicitHeight: 4 color: SplitHandle.pressed ? "#81e889" : (SplitHandle.hovered ? Qt.lighter("#c2f4c6", 1.1) : "#c2f4c6") } Rectangle { implicitWidth: 150 color: "#444" } Rectangle { implicitWidth: 50 color: "#666" } }
StackViewのカスタマイズ
StackView はビジュアルな アイテムを持つことができ、push、pop、replace 操作に使用されるトランジションをカスタマイズできます。background
import QtQuick import QtQuick.Controls.Basic StackView { id: control popEnter: Transition { XAnimator { from: (control.mirrored ? -1 : 1) * -control.width to: 0 duration: 400 easing.type: Easing.OutCubic } } popExit: Transition { XAnimator { from: 0 to: (control.mirrored ? -1 : 1) * control.width duration: 400 easing.type: Easing.OutCubic } } }
SwipeDelegateのカスタマイズ
SwipeDelegate は6つのビジュアル・アイテムから構成されています: , , , , 。background content item indicator swipe.left
swipe.right
swipe.behind
import QtQuick import QtQuick.Controls.Basic SwipeDelegate { id: control text: qsTr("SwipeDelegate") Component { id: component Rectangle { color: SwipeDelegate.pressed ? "#333" : "#444" width: parent.width height: parent.height clip: true Label { text: qsTr("Press me!") color: "#21be2b" anchors.centerIn: parent } } } swipe.left: component swipe.right: component contentItem: Text { text: control.text font: control.font color: control.enabled ? (control.down ? "#17a81a" : "#21be2b") : "#bdbebf" elide: Text.ElideRight verticalAlignment: Text.AlignVCenter Behavior on x { enabled: !control.down NumberAnimation { easing.type: Easing.InOutCubic duration: 400 } } } }
SwipeViewのカスタマイズ
SwipeView は、 のビジュアル・アイテムを持つことができます。ナビゲーションは によって実装されます。background content item
import QtQuick import QtQuick.Controls.Basic SwipeView { id: control background: Rectangle { color: "#eeeeee" } }
スイッチのカスタマイズ
Switchは3つのビジュアル・アイテムで構成されています:background content item とindicator 。
import QtQuick import QtQuick.Controls.Basic Switch { id: control text: qsTr("Switch") indicator: Rectangle { implicitWidth: 48 implicitHeight: 26 x: control.leftPadding y: parent.height / 2 - height / 2 radius: 13 color: control.checked ? "#17a81a" : "#ffffff" border.color: control.checked ? "#17a81a" : "#cccccc" Rectangle { x: control.checked ? parent.width - width : 0 width: 26 height: 26 radius: 13 color: control.down ? "#cccccc" : "#ffffff" border.color: control.checked ? (control.down ? "#17a81a" : "#21be2b") : "#999999" } } contentItem: Text { text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: control.down ? "#17a81a" : "#21be2b" verticalAlignment: Text.AlignVCenter leftPadding: control.indicator.width + control.spacing } }
SwitchDelegateのカスタマイズ
SwitchDelegate は3つのビジュアル・アイテムで構成されている: と 。background contentItem indicator
import QtQuick import QtQuick.Controls.Basic SwitchDelegate { id: control text: qsTr("SwitchDelegate") checked: true contentItem: Text { rightPadding: control.indicator.width + control.spacing text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: control.down ? "#17a81a" : "#21be2b" elide: Text.ElideRight verticalAlignment: Text.AlignVCenter } indicator: Rectangle { implicitWidth: 48 implicitHeight: 26 x: control.width - width - control.rightPadding y: parent.height / 2 - height / 2 radius: 13 color: control.checked ? "#17a81a" : "transparent" border.color: control.checked ? "#17a81a" : "#cccccc" Rectangle { x: control.checked ? parent.width - width : 0 width: 26 height: 26 radius: 13 color: control.down ? "#cccccc" : "#ffffff" border.color: control.checked ? (control.down ? "#17a81a" : "#21be2b") : "#999999" } } background: Rectangle { implicitWidth: 100 implicitHeight: 40 visible: control.down || control.highlighted color: control.down ? "#bdbebf" : "#eeeeee" } }
タブバーのカスタマイズ
TabBar は2つのビジュアル・アイテムで構成されています:と 。background contentItem
import QtQuick import QtQuick.Controls.Basic TabBar { id: control background: Rectangle { color: "#eeeeee" } TabButton { text: qsTr("Home") } TabButton { text: qsTr("Discover") } TabButton { text: qsTr("Activity") } }
タブボタンのカスタマイズ
TabButton もButtonと同様にカスタマイズできます。
テキストエリアのカスタマイズ
import QtQuick import QtQuick.Controls.Basic TextArea { id: control placeholderText: qsTr("Enter description") background: Rectangle { implicitWidth: 200 implicitHeight: 40 border.color: control.enabled ? "#21be2b" : "transparent" } }
TextFieldのカスタマイズ
import QtQuick import QtQuick.Controls.Basic TextField { id: control placeholderText: qsTr("Enter description") background: Rectangle { implicitWidth: 200 implicitHeight: 40 color: control.enabled ? "transparent" : "#353637" border.color: control.enabled ? "#21be2b" : "transparent" } }
ツールバーのカスタマイズ
ToolBar はひとつの視覚的なアイテムから構成されています: 。background
ToolBar { id: control background: Rectangle { implicitHeight: 40 color: "#eeeeee" Rectangle { width: parent.width height: 1 anchors.bottom: parent.bottom color: "transparent" border.color: "#21be2b" } } RowLayout { anchors.fill: parent ToolButton { text: qsTr("Undo") } ToolButton { text: qsTr("Redo") } } }
ツールボタンのカスタマイズ
ToolButton は、 と の 2 つのビジュアルアイテムで構成されます。background content item
import QtQuick import QtQuick.Controls.Basic ToolButton { id: control text: qsTr("ToolButton") width: 120 contentItem: Text { text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: control.down ? "#17a81a" : "#21be2b" horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { implicitWidth: 40 implicitHeight: 40 color: Qt.darker("#33333333", control.enabled && (control.checked || control.highlighted) ? 1.5 : 1.0) opacity: enabled ? 1 : 0.3 visible: control.down || (control.enabled && (control.checked || control.highlighted)) } }
ツールセパレーターのカスタマイズ
ToolSeparator は、 と の2つのビジュアルアイテムで構成されています。background content item
ToolBar { RowLayout { anchors.fill: parent ToolButton { text: qsTr("Action 1") } ToolButton { text: qsTr("Action 2") } ToolSeparator { padding: vertical ? 10 : 2 topPadding: vertical ? 2 : 10 bottomPadding: vertical ? 2 : 10 contentItem: Rectangle { implicitWidth: parent.vertical ? 1 : 24 implicitHeight: parent.vertical ? 24 : 1 color: "#c3c3c3" } } ToolButton { text: qsTr("Action 3") } ToolButton { text: qsTr("Action 4") } Item { Layout.fillWidth: true } } }
ツールチップのカスタマイズ
ToolTip は、 と の2つのビジュアル・アイテムで構成されています。background content item
import QtQuick import QtQuick.Controls.Basic ToolTip { id: control text: qsTr("A descriptive tool tip of what the button does") contentItem: Text { text: control.text font: control.font color: "#21be2b" } background: Rectangle { border.color: "#21be2b" } }
注: attached ToolTip をカスタマイズするには、独自のスタイルの一部として提供する必要があります。ToolTip
を単発的にカスタマイズするには、Custom Tool Tips を参照してください。
タンブラーのカスタマイズ
タンブラーは3つのビジュアルアイテムで構成されています:background contentItem 、delegate 。
import QtQuick import QtQuick.Controls.Basic Tumbler { id: control model: 15 background: Item { Rectangle { opacity: control.enabled ? 0.2 : 0.1 border.color: "#000000" width: parent.width height: 1 anchors.top: parent.top } Rectangle { opacity: control.enabled ? 0.2 : 0.1 border.color: "#000000" width: parent.width height: 1 anchors.bottom: parent.bottom } } delegate: Text { text: qsTr("Item %1").arg(modelData + 1) font: control.font horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter opacity: 1.0 - Math.abs(Tumbler.displacement) / (control.visibleItemCount / 2) required property var modelData required property int index } Rectangle { anchors.horizontalCenter: control.horizontalCenter y: control.height * 0.4 width: 40 height: 1 color: "#21be2b" } Rectangle { anchors.horizontalCenter: control.horizontalCenter y: control.height * 0.6 width: 40 height: 1 color: "#21be2b" } }
独自のcontentItemを定義したい場合は、ListView またはPathView をルートアイテムとして使用します。ラッピング・タンブラーにはPathView を使います:
Tumbler { id: tumbler contentItem: PathView { id: pathView model: tumbler.model delegate: tumbler.delegate clip: true pathItemCount: tumbler.visibleItemCount + 1 preferredHighlightBegin: 0.5 preferredHighlightEnd: 0.5 dragMargin: width / 2 path: Path { startX: pathView.width / 2 startY: -pathView.delegateHeight / 2 PathLine { x: pathView.width / 2 y: pathView.pathItemCount * pathView.delegateHeight - pathView.delegateHeight / 2 } } property real delegateHeight: tumbler.availableHeight / tumbler.visibleItemCount } }
ラッピングなしのタンブラーには、ListView を使用します:
Tumbler { id: tumbler contentItem: ListView { model: tumbler.model delegate: tumbler.delegate snapMode: ListView.SnapToItem highlightRangeMode: ListView.StrictlyEnforceRange preferredHighlightBegin: height / 2 - (height / tumbler.visibleItemCount / 2) preferredHighlightEnd: height / 2 + (height / tumbler.visibleItemCount / 2) clip: true } }
© 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.