- Qt 5.15
- Qt Quick Controls 1
- Qt Quick Controls 1 Examples
- Qt Quick Controls 1 - Touch Gallery
- Qt 5.15.18 Reference Documentation

# Qt Quick Controls 1 - Touch Gallery

Demonstrates UI controls for a touch interface.

Warning: The Qt Quick Controls 1 module is deprecated since Qt 5.12. Use the latest Qt Quick Controls module instead.

Touch Gallery demonstrates how to implement a UI suitable for touch input using the following Qt Quick Controls 1:

- ApplicationWindow
- Button
- ProgressBar
- ScrollView
- Slider
- StackView
- Switch
- Tab
- TabView
- TextField

The appearance of the controls is customized by using Qt Quick Controls 1 Styles.

#### Running the Example

To run the example from Qt Creator, open the Welcome mode and select the example from Examples. For more information, visit Building and Running an Example.

#### Creating the Main Page

In the main.qml file, we use a Rectangle type within the ApplicationWindow type to create the main page of the application:

     ApplicationWindow {
         visible: true
         width: 800
         height: 1280

         Rectangle {
             color: "#212126"
             anchors.fill: parent
         }

To use the Qt Quick Controls, we must import them:

     import QtQuick.Controls 1.2

The `toolBar` property of the application window holds a BorderImage type that we use to create a separator between the application name and a list of additional pages:

         toolBar: BorderImage {
             border.bottom: 8
             source: "images/toolbar.png"
             width: parent.width
             height: 100

We use an Image type in a Rectangle type to create a back button. We use the `onClicked` signal handler to call the StackView `pop()` function that pops off the page when users tap the button:

             Rectangle {
                 id: backButton
                 width: opacity ? 60 : 0
                 anchors.left: parent.left
                 anchors.leftMargin: 20
                 opacity: stackView.depth > 1 ? 1 : 0
                 anchors.verticalCenter: parent.verticalCenter
                 antialiasing: true
                 height: 60
                 radius: 4
                 color: backmouse.pressed ? "#222" : "transparent"
                 Behavior on opacity { NumberAnimation{} }
                 Image {
                     anchors.verticalCenter: parent.verticalCenter
                     source: "images/navigation_previous_item.png"
                 }
                 MouseArea {
                     id: backmouse
                     anchors.fill: parent
                     anchors.margins: -10
                     onClicked: stackView.pop()
                 }
             }

We use the `opacity` property to hide the back button on the main page.

We use a Text type to display the application name:

             Text {
                 font.pixelSize: 42
                 Behavior on x { NumberAnimation{ easing.type: Easing.OutCubic} }
                 x: backButton.x + backButton.width + 20
                 anchors.verticalCenter: parent.verticalCenter
                 color: "white"
                 text: "Widget Gallery"
             }

The `x` position of the Text type is bound to the position and width of the back button, and animated using a Behavior.

We use a ListModel type that contains ListElement definitions to define titles and source files for the other pages in the application:

         ListModel {
             id: pageModel
             ListElement {
                 title: "Buttons"
                 page: "content/ButtonPage.qml"
             }
             ListElement {
                 title: "Sliders"
                 page: "content/SliderPage.qml"
             }
             ListElement {
                 title: "ProgressBar"
                 page: "content/ProgressBarPage.qml"
             }
             ListElement {
                 title: "Tabs"
                 page: "content/TabBarPage.qml"
             }
             ListElement {
                 title: "TextInput"
                 page: "content/TextInputPage.qml"
             }
             ListElement {
                 title: "List"
                 page: "content/ListPage.qml"
             }
         }

#### Navigating in the Application

We implement a stack-based navigation model to link the application pages together. Items are pushed onto the stack as users navigate deeper into the application, and popped off again when they return to the main page.

In main.qml, we add a StackView type as a child of the application window:

         StackView {
             id: stackView
             anchors.fill: parent
             // Implements back key navigation
             focus: true
             Keys.onReleased: if (event.key === Qt.Key_Back && stackView.depth > 1) {
                                  stackView.pop();
                                  event.accepted = true;
                              }

The stack is used by invoking its navigation methods. To load the first item in the stack view, we assign it to `initialItem`:

             initialItem: Item {
                 width: parent.width
                 height: parent.height
                 ListView {
                     model: pageModel
                     anchors.fill: parent
                     delegate: AndroidDelegate {
                         text: title
                         onClicked: stackView.push(Qt.resolvedUrl(page))
                     }
                 }
             }
         }

     }

We use a ListView type to display a list of the items provided by `pageModel`. The `AndroidDelegate` custom type defines each item instantiated by the view.

#### Creating Push Buttons and Switches

In ButtonPage.qml we use the Button type to create two buttons that change color when users tap them and one that pops off the page and returns the user to the main page:

             Button {
                 text: "Press me"
                 style: touchStyle
             }

             Button {
                 style: touchStyle
                 text: "Press me too"
             }

             Button {
                 anchors.margins: 20
                 style: touchStyle
                 text: "Don't press me"
                 onClicked: if (stackView) stackView.pop()
             }

We use a Switch type to create two switches that users can turn on and off. They are placed within a Row type to lay them out horizontally:

             Row {
                 spacing: 20
                 Switch {
                     style: switchStyle
                 }
                 Switch {
                     style: switchStyle
                 }
             }

A ButtonStyle type creates a custom appearance for the buttons:

         Component {
             id: touchStyle
             ButtonStyle {
                 panel: Item {
                     implicitHeight: 50
                     implicitWidth: 320
                     BorderImage {
                         anchors.fill: parent
                         antialiasing: true
                         border.bottom: 8
                         border.top: 8
                         border.left: 8
                         border.right: 8
                         anchors.margins: control.pressed ? -4 : 0
                         source: control.pressed ? "../images/button_pressed.png" : "../images/button_default.png"
                         Text {
                             text: control.text
                             anchors.centerIn: parent
                             color: "white"
                             font.pixelSize: 23
                             renderType: Text.NativeRendering
                         }

To use Qt Quick Controls Styles, we must import them:

     import QtQuick.Controls.Styles 1.1

A SwitchStyle type creates a custom appearance for the switches:

         Component {
             id: switchStyle
             SwitchStyle {

                 groove: Rectangle {
                     implicitHeight: 50
                     implicitWidth: 152
                     Rectangle {
                         anchors.top: parent.top
                         anchors.left: parent.left
                         anchors.bottom: parent.bottom
                         width: parent.width/2 - 2
                         height: 20
                         anchors.margins: 2
                         color: control.checked ? "#468bb7" : "#222"
                         Behavior on color {ColorAnimation {}}
                         Text {
                             font.pixelSize: 23
                             color: "white"
                             anchors.centerIn: parent
                             text: "ON"
                         }
                     }
                     Item {
                         width: parent.width/2
                         height: parent.height
                         anchors.right: parent.right
                         Text {
                             font.pixelSize: 23
                             color: "white"
                             anchors.centerIn: parent
                             text: "OFF"
                         }
                     }
                     color: "#222"
                     border.color: "#444"
                     border.width: 2
                 }
                 handle: Rectangle {
                     width: parent.parent.width/2
                     height: control.height
                     color: "#444"
                     border.color: "#555"
                     border.width: 2
                 }
             }
         }
     }

The `groove` property holds the background groove of the switch and the `handle` property defines the switch handle.

#### Creating Sliders

In SliderPage.qml, we use a Slider type to create three horizontal sliders that are placed within a Column type to lay them out in a column:

         Column {
             spacing: 12
             anchors.centerIn: parent

             Slider {
                 anchors.margins: 20
                 style: touchStyle
                 value: 0
             }
             Slider {
                 anchors.margins: 20
                 style: touchStyle
                 value: 0.5
             }
             Slider {
                 anchors.margins: 20
                 style: touchStyle
                 value: 1.0
             }

         }

The `value` property holds the initial handle position on the slider.

A SliderStyle type creates a custom appearance for the sliders:

         Component {
             id: touchStyle
             SliderStyle {
                 handle: Rectangle {
                     width: 30
                     height: 30
                     radius: height
                     antialiasing: true
                     color: Qt.lighter("#468bb7", 1.2)
                 }

                 groove: Item {
                     implicitHeight: 50
                     implicitWidth: 400
                     Rectangle {
                         height: 8
                         width: parent.width
                         anchors.verticalCenter: parent.verticalCenter
                         color: "#444"
                         opacity: 0.8
                         Rectangle {
                             antialiasing: true
                             radius: 1
                             color: "#468bb7"
                             height: parent.height
                             width: parent.width * control.value / control.maximumValue
                         }
                     }
                 }
             }
         }
     }

The `handle` property defines the slider handle and the `groove` property holds the background groove of the slider.

#### Indicating Progress

In ProgressBar.qml, we use a ProgressBar type to create three progress bars:

         Column {
             spacing: 40
             anchors.centerIn: parent

             ProgressBar {
                 anchors.margins: 20
                 style: touchStyle
                 width: 400
                 value: progress
             }

             ProgressBar {
                 anchors.margins: 20
                 style: touchStyle
                 width: 400
                 value: 1 - progress
             }

             ProgressBar {
                 anchors.margins: 20
                 style: touchStyle
                 value: 1
                 width: 400
             }

We use a NumberAnimation type with a SequentialAnimation type to run two number animations in a sequence. We apply the animations on the `progress` custom property to animate the current value on the progress bars:

         property real progress: 0
         SequentialAnimation on progress {
             loops: Animation.Infinite
             running: true
             NumberAnimation {
                 from: 0
                 to: 1
                 duration: 3000
             }
             NumberAnimation {
                 from: 1
                 to: 0
                 duration: 3000
             }

A ProgressBarStyle type creates a custom appearance for the progress bars:

         Component {
             id: touchStyle
             ProgressBarStyle {
                 panel: Rectangle {
                     implicitHeight: 15
                     implicitWidth: 400
                     color: "#444"
                     opacity: 0.8
                     Rectangle {
                         antialiasing: true
                         radius: 1
                         color: "#468bb7"
                         height: parent.height
                         width: parent.width * control.value / control.maximumValue
                     }
                 }
             }
         }
     }

#### Creating Tabs

In TabBarPage.qml, we use a TabView type with a Tab type to provide a tab-based navigation model for our application. We use tabs to display the ButtonPage, SliderPage, and ProgressBarPage on separate tab pages:

         TabView {
             anchors.fill: parent
             style: touchStyle
             Tab {
                 title: "Buttons"
                 ButtonPage{ visible: true }
             }
             Tab {
                 title: "Sliders"
                 SliderPage{ visible: true }
             }
             Tab {
                 title: "Progress"
                 ProgressBarPage{ visible: true }
             }

A TabViewStyle type creates a custom appearance for the tabs:

         Component {
             id: touchStyle
             TabViewStyle {
                 tabsAlignment: Qt.AlignVCenter
                 tabOverlap: 0
                 frame: Item { }
                 tab: Item {
                     implicitWidth: control.width/control.count
                     implicitHeight: 50
                     BorderImage {
                         anchors.fill: parent
                         border.bottom: 8
                         border.top: 8
                         source: styleData.selected ? "../images/tab_selected.png":"../images/tabs_standard.png"
                         Text {
                             anchors.centerIn: parent
                             color: "white"
                             text: styleData.title.toUpperCase()
                             font.pixelSize: 16
                         }
                         Rectangle {
                             visible: index > 0
                             anchors.top: parent.top
                             anchors.bottom: parent.bottom
                             anchors.margins: 10
                             width:1
                             color: "#3a3a3a"
                         }
                     }
                 }
             }
         }
     }

#### Creating Text Input Fields

In the TextInputPage.qml, we use a TextField type to create an input field and a read-only text field:

         Column {
             spacing: 40
             anchors.centerIn: parent

             TextField {
                 anchors.margins: 20
                 text: "Text input"
                 style: touchStyle
             }

             TextField {
                 anchors.margins: 20
                 text: "Readonly Text input"
                 style: touchStyle
                 readOnly: true
             }
         }

A TextFieldStyle creates a custom appearance for the text fields:

         Component {
             id: touchStyle

             TextFieldStyle {
                 textColor: "white"
                 font.pixelSize: 28
                 background: Item {
                     implicitHeight: 50
                     implicitWidth: 320
                     BorderImage {
                         source: "../images/textinput.png"
                         border.left: 8
                         border.right: 8
                         anchors.bottom: parent.bottom
                         anchors.left: parent.left
                         anchors.right: parent.right
                     }
                 }
             }
         }
     }

We use a BorderImage type with an image to create borders for the fields.

#### Creating Scrolling Lists

In ListPage.qml, we use a ScrollView type to provide a scrolling page with a vertical scoll bar:

     ScrollView {
         width: parent.width
         height: parent.height

         flickableItem.interactive: true

We use a ListView type to display a list of 100 items by specifying an integer as the value of the `model` property. We reuse the `AndroidDelegate` custom type here to define each item instantiated by the view. The `text` property adds the string `Item #` to each list item:

         ListView {
             anchors.fill: parent
             model: 100
             delegate: AndroidDelegate {
                 text: "Item #" + modelData
             }
         }

A ScrollViewStyle type creates a custom appearance for the scroll view:

         style: ScrollViewStyle {
             transientScrollBars: true
             handle: Item {
                 implicitWidth: 14
                 implicitHeight: 26
                 Rectangle {
                     color: "#424246"
                     anchors.fill: parent
                     anchors.topMargin: 6
                     anchors.leftMargin: 4
                     anchors.rightMargin: 4
                     anchors.bottomMargin: 6
                 }
             }
             scrollBarBackground: Item {
                 implicitWidth: 14
                 implicitHeight: 26
             }
         }
     }

The `transientScrollBars` property is set to `true` to make the scroll bars appear when the content is scrolled and disappear when they are no longer needed.

The `handle` property controls the appearance of the scroll bar handle and the `scrollBarBackground` property that of the background.

Example project @ code.qt.io