Customizing Qt Labs Controls
Qt Labs Controls consist of a hierarchy (tree) of items. In order to provide a custom look and feel, the default QML implementation of each item can be replaced with a custom one. The following snippets present the default implementations of various items. These can be used as a starting point to implement a custom look and feel.
Customizing BusyIndicator
BusyIndicator consists of two visual items: background and contentItem.
Background
BusyIndicator has no background item by default.
Content item
contentItem: BusyRing { id: ring implicitWidth: 48 implicitHeight: 48 opacity: control.running ? 1 : 0 Behavior on opacity { OpacityAnimator { duration: 250 } } BusyRingAnimator { target: ring running: control.visible && control.running } }
Customizing Button
Button consists of two visual items: background and label.
Background
background: Rectangle { implicitWidth: 100 implicitHeight: 40 opacity: enabled ? 1 : 0.3 color: control.pressed ? (control.highlighted ? "#585a5c" : "#e4e4e4") : (control.highlighted ? "#353637" : "#f6f6f6") border.color: control.pressed ? "#26282a" : "#353637" }
Label
label: Text { x: control.leftPadding y: control.topPadding width: control.availableWidth height: control.availableHeight text: control.text font: control.font opacity: enabled || highlighted ? 1 : 0.3 color: control.highlighted ? "#ffffff" : (control.pressed ? "#26282a" : "#353637") horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight }
Customizing CheckBox
CheckBox consists of three visual items: background, label and indicator.
Background
CheckBox has no background item by default.
Label
label: Text { x: control.mirrored ? control.leftPadding : (indicator.x + indicator.width + control.spacing) y: control.topPadding width: control.availableWidth - indicator.width - control.spacing height: control.availableHeight text: control.text font: control.font color: control.pressed ? "#26282a" : "#353637" elide: Text.ElideRight visible: control.text horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter }
Indicator
indicator: Rectangle { implicitWidth: 28 implicitHeight: 28 x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 color: control.enabled ? (control.pressed ? "#e4e4e4" : "#f6f6f6") : "#353637" border.color: control.enabled ? (control.pressed ? "#26282a" : "#353637") : "transparent" Image { x: (parent.width - width) / 2 y: (parent.height - height) / 2 source: "qrc:/qt-project.org/imports/Qt/labs/controls/images/check.png" visible: control.checkState === Qt.Checked } Rectangle { x: (parent.width - width) / 2 y: (parent.height - height) / 2 width: 16 height: 3 color: "#353637" visible: control.checkState === Qt.PartiallyChecked } }
Customizing ComboBox
ComboBox consists of background, content item, popup, and delegate.
Background
background: Item { implicitWidth: 120 implicitHeight: 40 Rectangle { width: parent.width height: parent.height opacity: control.enabled ? 1.0 : 0.2 color: control.pressed || popup.visible ? "#585A5C" : "#353637" } Image { x: parent.width - width - control.rightPadding y: (parent.height - height) / 2 source: "qrc:/qt-project.org/imports/Qt/labs/controls/images/drop-indicator.png" } }
Content item
contentItem: Text { text: control.displayText font: control.font color: "#ffffff" horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter elide: Text.ElideRight rightPadding: 18 + control.spacing }
Popup
popup: T.Popup { y: control.height - 1 implicitWidth: control.width implicitHeight: listview.contentHeight topMargin: 6 bottomMargin: 6 contentItem: ListView { id: listview clip: true model: control.popup.visible ? control.delegateModel : null currentIndex: control.highlightedIndex Rectangle { z: 10 parent: listview width: listview.width height: listview.height border.color: "#353637" color: "transparent" } T.ScrollIndicator.vertical: ScrollIndicator { } } background: Rectangle { } }
Delegate
delegate: ItemDelegate { width: control.width text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData checkable: true autoExclusive: true checked: control.currentIndex === index highlighted: control.highlightedIndex === index pressed: highlighted && control.pressed }
Customizing Dial
Dial consists of two visual items: background and handle.
Background
background: Rectangle { x: control.width / 2 - width / 2 y: control.height / 2 - height / 2 width: Math.max(64, Math.min(control.width, control.height)) height: Math.max(64, Math.min(control.width, control.height)) radius: width / 2 border.color: "#353637" }
Indicator
handle: Image { id: handleItem x: background.x + background.width / 2 - handle.width / 2 y: background.y + background.height / 2 - handle.height / 2 width: 14 height: 10 source: "qrc:/qt-project.org/imports/Qt/labs/controls/images/dial-indicator.png" antialiasing: true transform: [ Translate { y: -background.height * 0.4 + handle.height / 2 }, Rotation { angle: control.angle origin.x: handle.width / 2 origin.y: handle.height / 2 } ] }
Customizing Drawer
Drawer can have a visual background item. The navigation is implemented by the content item.
Background
Content item
Drawer has no content item by default.
Customizing Frame
Frame consists of two visual items: background and frame.
Background
Frame has no background item by default.
Frame
frame: Rectangle { width: parent.width height: parent.height color: "transparent" border.color: "#bdbebf" }
Customizing GroupBox
GroupBox consists of three visual items: background, frame and label.
Background
GroupBox has no background item by default.
Frame
frame: Rectangle { y: control.topPadding - control.padding width: parent.width height: parent.height - control.topPadding + control.padding color: "transparent" border.color: "#bdbebf" }
Label
label: Text { x: control.leftPadding width: control.availableWidth text: control.title font: control.font color: control.enabled ? "#353637" : "#bdbebf" elide: Text.ElideRight horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter }
Customizing ItemDelegate
ItemDelegate consists of three visual items: background, label and indicator. The indicator is only visible for checkable items.
Background
background: Rectangle { implicitWidth: 100 implicitHeight: 40 visible: control.pressed || control.highlighted color: control.pressed ? "#bdbebf" : "#eeeeee" }
Label
label: Text { x: control.mirrored ? control.width - width - control.rightPadding : control.leftPadding y: control.topPadding width: control.availableWidth - (control.checkable ? indicator.width + control.spacing : 0) height: control.availableHeight text: control.text font: control.font color: control.enabled ? "#26282a" : "#bdbebf" elide: Text.ElideRight visible: control.text horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter }
Indicator
indicator: Image { x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding y: control.topPadding + (control.availableHeight - height) / 2 visible: control.checked source: control.checkable ? "qrc:/qt-project.org/imports/Qt/labs/controls/images/check.png" : "" }
Customizing Label
Label can have a visual background item.
Background
Label has no background item by default.
Customizing Menu
Menu consists of a contentItem.
Content item
contentItem: ListView { implicitHeight: contentHeight model: control.contentModel // TODO: improve this? interactive: ApplicationWindow.window ? contentHeight > ApplicationWindow.window.height : false clip: true keyNavigationWraps: false currentIndex: -1 ScrollIndicator.vertical: ScrollIndicator {} }
Customizing MenuItem
MenuItem can be customized in the same manner as Button.
Customizing PageIndicator
TODO
Customizing Pane
Pane consists of a background.
Background
background: Rectangle { color: "#ffffff" }
Customizing ProgressBar
ProgressBar consists of two visual items: background and indicator.
Background
background: Rectangle { implicitWidth: 200 implicitHeight: 6 x: control.leftPadding y: control.topPadding + (control.availableHeight - height) / 2 width: control.availableWidth height: 6 color: "#e4e4e4" }
Indicator
indicator: ProgressStrip { id: strip x: control.leftPadding y: control.topPadding + (control.availableHeight - height) / 2 width: control.availableWidth height: 6 scale: control.mirrored ? -1 : 1 progress: control.position indeterminate: control.indeterminate ProgressStripAnimator { target: strip running: control.visible && control.indeterminate } }
Customizing RadioButton
RadioButton consists of three visual items: background, label and indicator.
Background
RadioButton has no background item by default.
Label
label: Text { x: control.mirrored ? control.leftPadding : (indicator.x + indicator.width + control.spacing) y: control.topPadding width: control.availableWidth - indicator.width - control.spacing height: control.availableHeight text: control.text font: control.font color: control.pressed ? "#26282a" : "#353637" elide: Text.ElideRight visible: control.text horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter }
Indicator
indicator: Rectangle { implicitWidth: 28 implicitHeight: 28 x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 radius: width / 2 border.width: 1 border.color: (control.pressed ? "#26282a" : "#353637") color: control.pressed ? "#e4e4e4" : "#f6f6f6" Rectangle { x: (parent.width - width) / 2 y: (parent.height - height) / 2 width: 20 height: 20 radius: width / 2 color: control.pressed ? "#26282a" : "#353637" visible: control.checked } }
Customizing RangeSlider
RangeSlider consists of four visual items: background, track, first.handle and second.handle.
Background
RangeSlider has no background item by default.
Track
track: Rectangle { x: control.leftPadding + (horizontal ? 0 : (control.availableWidth - width) / 2) y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : 0) implicitWidth: horizontal ? 200 : 6 implicitHeight: horizontal ? 6 : 200 width: horizontal ? control.availableWidth : implicitWidth height: horizontal ? implicitHeight : control.availableHeight radius: 3 border.color: "#353637" color: "#ffffff" scale: horizontal && control.mirrored ? -1 : 1 readonly property bool horizontal: control.orientation === Qt.Horizontal }
First Handle
first.handle: Rectangle { x: control.leftPadding + (horizontal ? control.first.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.first.visualPosition * (control.availableHeight - height)) implicitWidth: 28 implicitHeight: 28 radius: width / 2 border.width: activeFocus ? 2 : 1 border.color: "#353637" color: first.pressed ? "#bdbebf" : "#ffffff" readonly property bool horizontal: control.orientation === Qt.Horizontal }
Second Handle
second.handle: Rectangle { x: control.leftPadding + (horizontal ? control.second.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.second.visualPosition * (control.availableHeight - height)) implicitWidth: 28 implicitHeight: 28 radius: width / 2 border.width: activeFocus ? 2 : 1 border.color: "#353637" color: second.pressed ? "#bdbebf" : "#ffffff" readonly property bool horizontal: control.orientation === Qt.Horizontal }
Customizing ScrollBar
ScrollBar consists of two visual items: background and handle.
Background
ScrollBar has no background item by default.
Handle
handle: Rectangle { id: handle implicitWidth: 6 implicitHeight: 6 radius: width / 2 color: control.pressed ? "#28282a" : "#bdbebf" visible: control.size < 1.0 opacity: 0.0 readonly property bool horizontal: control.orientation === Qt.Horizontal x: control.leftPadding + (horizontal ? control.position * control.availableWidth : 0) y: control.topPadding + (horizontal ? 0 : control.position * control.availableHeight) width: horizontal ? control.size * control.availableWidth : implicitWidth height: horizontal ? implicitHeight : control.size * control.availableHeight states: State { name: "active" when: control.active PropertyChanges { target: handle; opacity: 0.75 } } transitions: Transition { from: "active" SequentialAnimation { PauseAnimation { duration: 450 } NumberAnimation { target: handle; duration: 200; property: "opacity"; to: 0.0 } } } }
Customizing ScrollIndicator
ScrollIndicator consists of two visual items: background and indicator.
Background
ScrollIndicator has no background item by default.
Indicator
indicator: Rectangle { id: indicator implicitWidth: 2 implicitHeight: 2 color: "#bdbebf" visible: control.size < 1.0 opacity: 0.0 readonly property bool horizontal: control.orientation === Qt.Horizontal x: control.leftPadding + (horizontal ? control.position * control.width : 0) y: control.topPadding + (horizontal ? 0 : control.position * control.height) width: horizontal ? control.size * control.availableWidth : implicitWidth height: horizontal ? implicitHeight : control.size * control.availableHeight states: State { name: "active" when: control.active PropertyChanges { target: indicator; opacity: 0.75 } } transitions: [ Transition { from: "active" SequentialAnimation { PauseAnimation { duration: 450 } NumberAnimation { target: indicator; duration: 200; property: "opacity"; to: 0.0 } } } ] }
Customizing Slider
Slider consists of three visual items: background, track and handle.
Background
Slider has no background item by default.
Track
track: Rectangle { x: control.leftPadding + (horizontal ? 0 : (control.availableWidth - width) / 2) y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : 0) implicitWidth: horizontal ? 200 : 6 implicitHeight: horizontal ? 6 : 200 width: horizontal ? control.availableWidth : implicitWidth height: horizontal ? implicitHeight : control.availableHeight radius: 3 border.color: "#353637" color: "#ffffff" scale: horizontal && control.mirrored ? -1 : 1 readonly property bool horizontal: control.orientation === Qt.Horizontal }
Handle
handle: Rectangle { x: control.leftPadding + (horizontal ? control.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.visualPosition * (control.availableHeight - height)) implicitWidth: 28 implicitHeight: 28 radius: width / 2 border.color: "#353637" color: control.pressed ? "#bdbebf" : "#f6f6f6" readonly property bool horizontal: control.orientation === Qt.Horizontal }
Customizing SpinBox
SpinBox consists of four visual items: background, contentItem, up indicator, and down indicator.
Background
background: Rectangle { implicitWidth: 140 border.color: "#bdbebf" }
Content item
contentItem: TextInput { text: control.textFromValue(control.value, control.locale) font: control.font color: "#353637" selectionColor: "#fddd5c" selectedTextColor: color horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter validator: control.validator inputMethodHints: Qt.ImhFormattedNumbersOnly }
Down indicator
down.indicator: Rectangle { x: control.mirrored ? parent.width - width : 0 height: parent.height implicitWidth: 40 implicitHeight: 40 color: down.pressed ? "#e4e4e4" : "#f6f6f6" border.color: control.enabled ? "#353637" : "#bdbebf" Rectangle { x: (parent.width - width) / 2 y: (parent.height - height) / 2 width: parent.width / 3 height: 2 color: control.enabled ? "#353637" : "#bdbebf" } }
Up indicator
up.indicator: Rectangle { x: control.mirrored ? 0 : parent.width - width height: parent.height implicitWidth: 40 implicitHeight: 40 color: up.pressed ? "#e4e4e4" : "#f6f6f6" border.color: control.enabled ? "#353637" : "#bdbebf" Rectangle { x: (parent.width - width) / 2 y: (parent.height - height) / 2 width: parent.width / 3 height: 2 color: control.enabled ? "#353637" : "#bdbebf" } Rectangle { x: (parent.width - width) / 2 y: (parent.height - height) / 2 width: 2 height: parent.width / 3 color: control.enabled ? "#353637" : "#bdbebf" } }
Customizing StackView
StackView can have a visual background item, and it allows customizing the transitions that are used for push, pop, and replace operations.
Push enter
pushEnter: Transition { XAnimator { from: (root.mirrored ? -1 : 1) * root.width; to: 0; duration: 400; easing.type: Easing.OutCubic } }
Push exit
pushExit: Transition { XAnimator { from: 0; to: (root.mirrored ? -1 : 1) * -root.width; duration: 400; easing.type: Easing.OutCubic } }
Pop enter
popEnter: Transition { XAnimator { from: (root.mirrored ? -1 : 1) * -root.width; to: 0; duration: 400; easing.type: Easing.OutCubic } }
Pop exit
popExit: Transition { XAnimator { from: 0; to: (root.mirrored ? -1 : 1) * root.width; duration: 400; easing.type: Easing.OutCubic } }
Replace enter
replaceEnter: Transition { XAnimator { from: (root.mirrored ? -1 : 1) * root.width; to: 0; duration: 400; easing.type: Easing.OutCubic } }
Replace exit
replaceExit: Transition { XAnimator { from: 0; to: (root.mirrored ? -1 : 1) * -root.width; duration: 400; easing.type: Easing.OutCubic } }
Customizing SwipeView
SwipeView can have a visual background item. The navigation is implemented by the content item.
Background
SwipeView has no background item by default.
Content item
contentItem: ListView { model: control.contentModel currentIndex: control.currentIndex spacing: control.spacing orientation: Qt.Horizontal snapMode: ListView.SnapOneItem boundsBehavior: Flickable.StopAtBounds highlightRangeMode: ListView.StrictlyEnforceRange preferredHighlightBegin: 0 preferredHighlightEnd: 0 highlightMoveDuration: 250 }
Customizing Switch
Switch consists of three visual items: background, label and indicator.
Background
Switch has no background item by default.
Label
label: Text { x: control.mirrored ? control.leftPadding : (indicator.x + indicator.width + control.spacing) y: control.topPadding width: control.availableWidth - indicator.width - control.spacing height: control.availableHeight text: control.text font: control.font color: control.enabled ? "#26282a" : "#bdbebf" elide: Text.ElideRight visible: control.text horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter }
Indicator
indicator: Item { x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 implicitWidth: 56 implicitHeight: 28 Rectangle { y: parent.height / 2 - height / 2 width: 56 height: 16 radius: 8 border.width: 1 color: control.checked ? "#353637" : "transparent" border.color: control.checked ? "transparent" : "#353637" } Rectangle { x: Math.max(0, Math.min(parent.width - width, control.visualPosition * parent.width - (width / 2))) y: (parent.height - height) / 2 width: 28 height: 28 radius: 16 color: control.pressed ? "#e4e4e4" : "#f6f6f6" border.width: 1 border.color: control.pressed ? "#26282a" : "#353637" Behavior on x { enabled: !control.pressed SmoothedAnimation { velocity: 200 } } } }
Customizing TabBar
TODO
Customizing TabButton
TODO
Customizing TextArea
TODO
Customizing TextField
TextField offers a customizable background item.
Background
background: Rectangle { implicitWidth: 200 implicitHeight: 40 // border.width: control.activeFocus ? 2 : 1 color: control.enabled ? "transparent" : "#353637" border.color: control.enabled ? "#bdbebf" : "transparent" }
Customizing ToolBar
ToolBar consists of two visual items: background and frame.
Background
background: Rectangle { implicitHeight: 40 color: "#eeeeee" }
Frame
ToolBar has no frame item by default.
Customizing ToolButton
ToolButton consists of two visual items: background and label.
Background
background: Rectangle { implicitWidth: 40 implicitHeight: 40 color: Qt.darker("#33333333", control.enabled && (control.checked || control.highlighted) ? 1.5 : 1.0) opacity: control.pressed ? 1.0 : control.enabled && (control.checked || control.highlighted) ? 0.5 : 0 visible: control.pressed || (control.enabled && (control.checked || control.highlighted)) }
Label
label: Text { x: control.leftPadding y: control.topPadding width: control.availableWidth height: control.availableHeight text: control.text font: control.font color: control.enabled ? "#26282a" : "#c2c2c2" elide: Text.ElideRight horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter }
Customizing Tumbler
Tumbler consists of three visual items: background, contentItem, and delegate.
Background
Tumbler has no background item by default.
Content Item
contentItem: PathView { id: pathView model: control.model delegate: control.delegate clip: true pathItemCount: control.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: control.availableHeight / control.visibleItemCount }
Delegate
delegate: Text { id: label text: modelData color: "#666666" font: control.font opacity: 0.4 + Math.max(0, 1 - Math.abs(Tumbler.displacement)) * 0.6 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter }
© 2017 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.