Tutorial: Qt Quick application
This tutorial illustrates how to use Qt VS Tools to create a Qt Quick application. You will create a project using a project wizard and design a Qt Quick UI. In addition, you will learn how to add QML module definitions and QML files to your projects.
Before you start
Before you start, you have to:
Create a Qt Quick application project
To create a Qt Quick application project in Visual Studio:
- Go to File > New > Project.
- Search for Qt Quick Application.
- Select the project wizard, and then select Next.
- In Project name, enter QuickAddressBook, and then select Create.
- To acknowledge the Welcome dialog, select Next.
- To set up debug and release build configurations, click in Qt Modules, and select the Qt Quick and Qt Quick Controls modules to include in the project:
- Select Finish to create the project.
You now have a small working Qt Quick application. Go to Build > Build Solution to build it, and then go to Debug > Start Without Debugging (or press Ctrl+F5) to run it. For now, the result is an empty window.
Design the main window
The wizard created a main QML file for you, which declares a root object of the type Window. Change the file to design the application's main window.
Specify values for the Window color
and title
properties to set the background color and title of the application main window:
Window { id: mainWindow visible: true width: 480 height: 640 color: "darkgray" title: qsTr("Address Book")
Add a button
To create the Add button, declare an object of the Button type from the Qt Quick Controls module. Set the value of the button text
property to Add and the value of the font.pointSize
property to 24:
Button { id: addButton anchors.left: parent.left anchors.right: parent.right text: "Add..." font.pointSize: 24
When you run the application, you should now see this:
Connect the button to an action
QML has a signal and handler mechanism, where the signal is the event and the signal is responded to through a signal handler. When a signal is emitted, the corresponding signal handler is invoked. Placing logic such as a script or other operations in the handler allows the component to respond to the event.
To receive a notification when a particular signal is emitted for a particular object, the object definition should declare a signal handler named on<Signal>
, where <Signal>
is the name of the signal, with the first letter capitalized. The signal handler should contain the JavaScript code to be executed when the signal handler is invoked.
The Button type has a clicked
signal, which is emitted when the users click the button. To invoke a popup for adding an address book entry when the users select the Add button in the main window, you must connect the onClicked
signal handler of the button to the open()
method of the popup. You will add the popup as a separate QML type later.
onClicked: newAddressPopup.open() }
Add a list model
Within the Window, declare an object of the ListModel type with the id
addressList for storing the contact data. A list model defines a free-form list data source:
ListModel { id: addressList }
Declare a popup
Declare an object of the custom NewAddressPopup
type that defines the popup where the users will add address book entries. Use the onAddressAdded
signal handler to append address book entries to the addressList model:
NewAddressPopup { id: newAddressPopup onAddressAdded: addressList.append({name: newName, addr: newAddr}) }
You will create the NewAddressPopup
type later.
Position the button
Declare an object of ColumnLayout type to position the Button object and an instance of the Repeater type:
ColumnLayout { id: mainWindowLayout anchors.left: parent.left; anchors.right: parent.right spacing: 0 Button { id: addButton anchors.left: parent.left anchors.right: parent.right text: "Add..." font.pointSize: 24 onClicked: newAddressPopup.open() }
Anchor the column layout to the left and right edges of its parent to make the application scalable on different screen sizes. Set the spacing
between the rows in the column to 0.
Add a repeater
The Repeater type creates many similar items. It has a model and a delegate: for each entry in the model, the delegate is instantiated in a context seeded with data from the model. Enclose the repeater in an instance of a positioner type such as a ColumnLayout to visually position the delegate items that the repeater creates.
Specify addressList as the model
to use for the repeater:
Repeater { id: addressListViewer model: addressList anchors.left: parent.left anchors.right: parent.right
Declare an object of the custom AddressBookItem
type that the repeater will use to instantiate address book entries:
AddressBookItem { id: addressBookItem
You will create the AddressBookItem
type later.
Connect the Remove button to an action
Use the onRemoved
signal handler to remove an address book entry from the list when the user clicks its Remove button.
onRemoved: addressList.remove(index) }
Add a popup
Now that the main window is ready, move on to create the popup where users can add address book entries. The AddressBookItem
type specifies that the repeater instantiates the data that the users enter in the main window.
Use a Qt file wizard in Visual Studio to create a custom type that defines the popup.
To create custom QML types, you must first add a QML Module Definition (qmldir
) file to the project.
Add a QML module definition
A QML module definition (qmldir
) maps each custom QML type to its corresponding source file.
To add a QML module definition, go to Project > Add New Item > Installed > Visual C++ > Qt > Qt QML Module Definition > Add.
In the qmldir
file, add QML type definitions for AddressBookItem and NewAddressPopup:
AddressBookItem 1.0 AddressBookItem.qml NewAddressPopup 1.0 NewAddressPopup.qml
Next, you will create the QML types.
Create a popup
To add a custom QML type to the project:
- Go to Project > Add New Item > Installed > Visual C++ > Qt > Qt QML File.
- Select Add.
- In Name, enter NewAddressPopup.
- Select Finish to create a custom QML type.
Design the popup
In NewAddressPopup.qml, declare a root object of the type Popup to create a popup that opens in a Window. A popup does not provide a layout of its own, so you will use a ColumnLayout and a RowLayout to position the Name and E-Mail Address fields.
Popup { id: newAddressPopup
Set the modal
property to true
to specify that the popup is modal. Set the focus
property to true
to specify that the popup requests focus:
modal: true focus: true
Specify values for the width
, x
, and y
properties to set the position and size of the popup on top of the main window:
width: parent.width * 0.9 x: (parent.width - width) / 2 y: 35
Reset popup controls
When the popup opens, the Name and E-Mail Address fields should display placeholder text and any values entered previously should be cleared. You use the onOpened
signal handler to reset the values of the fields and give focus to the Name field:
onOpened: { nameField.text = ""; addrField.text = ""; nameField.focus = true; }
Position fields
Use an instance of the ColumnLayout type to position the TextField objects that specify the Name and E-Mail Address fields of the popup:
ColumnLayout { anchors.fill: parent TextField { id: nameField placeholderText: qsTr("Name") font.pointSize: 24 background: Rectangle { color: "lightgray" } Layout.preferredWidth: newAddressPopup / 2 Layout.fillWidth: true } TextField { id: addrField placeholderText: qsTr("E-Mail Address") font.pointSize: 24 background: Rectangle { color: "lightgray" } Layout.preferredWidth: newAddressPopup / 2 Layout.fillWidth: true }
Position buttons
Use an instance of a RowLayout type to position two Button objects that specify the Add and Cancel buttons:
RowLayout { anchors.left: parent.left; anchors.right: parent.right Button { text: "Add" enabled: nameField.length > 0 && addrField.length > 0 font.pointSize: 24 Layout.preferredWidth: newAddressPopup / 2 Layout.fillWidth: true
Connect buttons to actions
When the users click the Add button, the values they entered to the Name and E-Mail Address fields are added to the address list in the main window and the popup is closed.
To enable this, add the addressAdded(string newName, string newAddr)
signal:
signal addressAdded(string newName, string newAddr)
Connect the onClicked
signal handler of the Add button to the addressAdded()
signal and to the popup's close()
method:
Button { text: "Add" enabled: nameField.length > 0 && addrField.length > 0 font.pointSize: 24 Layout.preferredWidth: newAddressPopup / 2 Layout.fillWidth: true onClicked: { newAddressPopup.addressAdded(nameField.text, addrField.text) newAddressPopup.close() } }
For the Cancel button, connect the onClicked
signal handler to the to the popup's close()
method to close the popup without saving the data:
Button { text: "Cancel" font.pointSize: 24 Layout.preferredWidth: newAddressPopup / 2 Layout.fillWidth: true onClicked: newAddressPopup.close() }
Define an address book entry
The custom AddressBookItem
type specifies how to present address book entries in the main window.
Go to Project > Add New Item > Installed > Visual C++ > Qt > Qt QML File and select Add to create a new QML file called AddressBookItem.qml.
Design the entry
First, you will declare a root object of type Rectangle. It is one of the basic building blocks you can use to create an application in QML. Give it an id
to be able to refer to it later.
Rectangle { id: addressBookItem
To use alternating colors for rows, set the value of the color
property:
color: (index % 2) == 0 ? "dimgray" : "lightgray"
Anchor the rectangle to the left and right edges of its parent to make the application scalable on different screen sizes. Bind the rectangle height
property to the height of the text items it will contain:
anchors.left: parent.left anchors.right: parent.right height: itemText.height + 12
Connect the Remove button to an action
Add the removed()
signal that you will connect to the onClicked signal handler of the remove button. This removes an address book entry from the main window when users click the button:
signal removed()
Position the button and text
Use instances of the RoundButton and Text types within an instance of a RowLayout type to define an address book entry:
RowLayout { spacing: 12 anchors.left: parent.left anchors.leftMargin: spacing RoundButton { id: deleteButton text: "🗙" font.pointSize: 12 palette.buttonText: "red" onClicked: addressBookItem.removed() }
Format the text
Set the value of the text
property to combine the values of the name
and addr
fields from the popup and to use bold and italic formatting for the values:
Text { id: itemText font.pointSize: 24 text: "<b>" + name + "</b><br><i>" + addr + "</i>" }
Your application is now complete.
See also Tutorial: Qt Quick debugging and Tutorial: Qt Widgets application.
© 2024 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.