On this page
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
}
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/archives/qt-5.6/qtlabscontrols-customize.html