教程:Qt Quick应用程序

本教程说明了如何使用Qt VS工具创建一个Qt Quick应用程序。您将使用项目向导创建一个项目并设计一个Qt Quick UI。此外,您还将了解如何将QML模块定义和QML文件添加到项目中。

在开始之前

在开始之前,您必须

创建Qt Quick应用程序项目

要在Visual Studio中创建Qt Quick应用程序项目

  1. 转到 文件 > 新建 > 项目
  2. 搜索Qt Quick应用程序
  3. 选择项目向导,然后选择下一步
  4. 项目名称中输入QuickAddressBook,然后选择创建
  5. 要确认欢迎对话框,请选择下一步
  6. 要设置调试和发布构建配置,请单击Qt模块中的相应位置,然后选择要包含在项目中的Qt QuickQt Quick Controls模块

    {Selecting Qt modules in Qt Quick Application Wizard}

  7. 选择完成以创建项目。

现在您拥有了一个小型工作Qt Quick应用程序。转到构建 > 构建解决方案以构建它,然后转到调试 > 不进行调试启动(或按Ctrl+F5)以运行它。目前,结果是空窗口。

设计主窗口

向导已为您创建了一个主要的QML文件,该文件声明一个窗口类型的根对象。修改该文件以设计应用程序的主窗口。

指定Window的colortitle属性值以设置应用程序主窗口的背景颜色和标题

Window {
    id: mainWindow
    visible: true
    width: 480
    height: 640
    color: "darkgray"
    title: qsTr("Address Book")

添加一个按钮

要创建添加按钮,从Qt Quick Controls模块中声明一个按钮类型的对象。将按钮的text属性值设置为添加,并将font.pointSize属性值设置为24

        Button {
            id: addButton
            anchors.left: parent.left
            anchors.right: parent.right
            text: "Add..."
            font.pointSize: 24

当您运行应用程序时,您现在应该能看到这个

QuickAddressBook's main window

将按钮连接到操作

QML拥有信号和处理器机制,其中信号是事件,通过信号处理器来响应信号。当发出信号时,相应的信号处理器将被调用。在处理程序中放置逻辑,例如脚本或其他操作,可以让组件响应该事件。

要接收特定对象发出特定信号的通知,对象定义应声明一个名为on的信号处理器,其中<Signal>是信号名称,首字母大写。信号处理器应包含在调用信号处理器时要执行的JavaScript代码。

Button类型具有一个clicked信号,该信号在用户单击按钮时发出。要在使用户在主窗口中选择添加按钮时调用用于添加地址簿条目的弹出窗口,必须将按钮的onClicked信号处理器连接到弹出窗口的open()方法。您将在稍后添加该弹出窗口作为单独的QML类型。

            onClicked: newAddressPopup.open()
        }

添加列表模型

QuickAddressBook entries

在窗口中,声明一个具有id addressListListModel类型的对象来存储联系数据。列表模型定义了一个自由形式的列表数据源

    ListModel {
        id: addressList
    }

声明一个弹出窗口

声明一个自定义的NewAddressPopup类型的对象,该对象定义了用户将添加地址簿条目的弹出窗口。使用onAddressAdded信号处理器将地址簿条目追加到addressList模型

    NewAddressPopup {
        id: newAddressPopup
        onAddressAdded: addressList.append({name: newName, addr: newAddr})
    }

您将在稍后创建NewAddressPopup类型。

定位按钮

声明一个具有ColumnLayout类型的对象以定位Button对象和Repeater类型的实例

    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()
        }

将列布局锚定到父级的左边缘和右边缘,以使应用程序在不同屏幕尺寸上可扩展。将列中行之间的spacing设置为0

添加一个重复器

Repeater类型创建许多类似的项目。它具有模型和代理:对于模型中的每个条目,代理都将在通过模型数据种植的上下文中实例化。将重复器封装在位于例如ColumnLayout实例中的位置器类型中,以视觉上定位重复器创建的代理项。

addressList指定为重复器要使用的模型

        Repeater {
            id: addressListViewer
            model: addressList
            anchors.left: parent.left
            anchors.right: parent.right

声明自定义的AddressBookItem类型的对象,该对象用于重复器实例化地址簿条目

            AddressBookItem {
                id: addressBookItem

您将在稍后创建AddressBookItem类型。

将移除按钮连接到操作

使用onRemoved信号处理器在用户单击其移除按钮时从列表中删除地址簿条目。

                onRemoved: addressList.remove(index)
            }

添加一个弹出窗口

现在主窗口已准备就绪,继续创建用户可以添加地址簿条目的弹出窗口。AddressBookItem类型指定了重复器实例化用户在主窗口中输入的数据。

QuickAddressBook's popup

使用Visual Studio中的Qt文件向导创建自定义类型以定义弹出窗口。

要创建自定义QML类型,首先必须将QML模块定义(qmldir)文件添加到项目中。

添加QML模块定义

QML模块定义(qmldir)将每个自定义QML类型映射到相应的源文件。

要添加QML模块定义,请转到 项目 > 添加新项目 > 已安装 > Visual C++ > Qt > Qt QML模块定义 > 添加

qmldir文件中,为AddressBookItemNewAddressPopup添加QML类型定义

AddressBookItem    1.0    AddressBookItem.qml
NewAddressPopup    1.0    NewAddressPopup.qml

接下来,你将创建QML类型。

创建一个弹出窗口

要将自定义QML类型添加到项目

  1. 转到 项目 > 添加新项目 > 已安装 > Visual C++ > Qt > Qt QML文件
  2. 选择 添加
  3. 名称中输入NewAddressPopup
  4. 选择完成以创建自定义QML类型。

设计弹出窗口

NewAddressPopup.qml中,声明一个Popup类型的根对象来创建一个在窗口中打开的弹出窗口。弹出窗口不提供自己的布局,因此你将使用ColumnLayoutRowLayout来定位名称电子邮件地址字段。

Popup {
    id: newAddressPopup

modal属性设置为true以指定弹出窗口是模态的。将focus属性设置为true以指定弹出窗口请求焦点

    modal: true
    focus: true

指定widthxy属性以设置弹出窗口在主窗口上的位置和大小

    width: parent.width * 0.9
    x: (parent.width - width) / 2
    y: 35

重置弹出窗口控件

当弹出窗口打开时,名称电子邮件地址字段应显示占位符文本,并且之前输入的任何值都应被清除。你使用onOpened信号处理程序来重置字段的值并将焦点给予名称字段

    onOpened: {
        nameField.text = "";
        addrField.text = "";
        nameField.focus = true;
    }

定位字段

使用ColumnLayout类型的实例来定位指定弹出窗口名称电子邮件地址字段的TextField对象

    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
        }

定位按钮

使用RowLayout类型的实例来定位两个Button对象,分别指定弹出窗口的添加取消按钮

        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

将按钮连接到操作

当用户点击添加按钮时,他们输入到名称电子邮件地址字段的值将添加到主窗口中的地址列表中,并将弹出窗口关闭。

要启用此功能,请添加addressAdded(string newName, string newAddr)信号

    signal addressAdded(string newName, string newAddr)

添加按钮的onClicked信号处理器连接到addressAdded()信号,以及弹出框的close()方法

            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()
                }
            }

对于取消按钮,将onClicked信号处理器连接到弹出框的close()方法,以便在不保存数据的情况下关闭弹出框

            Button {
                text: "Cancel"
                font.pointSize: 24
                Layout.preferredWidth: newAddressPopup / 2
                Layout.fillWidth: true
                onClicked: newAddressPopup.close()
            }

定义一个通讯录条目

自定义的AddressBookItem类型指定了如何在主窗口中表示通讯录条目。

转到项目 > 添加新项 > 安装 > Visual C++ > Qt > Qt QML 文件,然后选择添加,创建一个名为 AddressBookItem.qml 的新 QML 文件。

设计条目

首先,您将声明一个类型为 矩形 的根对象。它是您可以使用来创建 QML 应用程序的基本构建块之一。给它一个 id 以便稍后引用。

Rectangle {
    id: addressBookItem

为了为行设置交替颜色,设置 color 属性的值

    color: (index % 2) == 0 ? "dimgray" : "lightgray"

将矩形定位在其父元素的左边缘和右边缘处,以使应用程序能够在不同屏幕尺寸上伸缩。将矩形的 height 属性绑定到它将包含的文本项的高度

    anchors.left: parent.left
    anchors.right: parent.right
    height: itemText.height + 12

将移除按钮连接到操作

添加一个 removed() 信号,将其连接到删除按钮的 onClicked 信号处理器。当用户单击按钮时,这将从主窗口中删除通讯录条目

    signal removed()

定位按钮和文本

圆形按钮文本 类型的一个实例中,使用 行布局 类型的实例来定义通讯录条目

    RowLayout {
        spacing: 12
        anchors.left: parent.left
        anchors.leftMargin: spacing
        RoundButton {
            id: deleteButton
            text: "🗙"
            font.pointSize: 12
            palette.buttonText: "red"
            onClicked: addressBookItem.removed()
        }

格式化文本

text 属性的值设置为从弹出框中合并 nameaddr 字段,并使用粗体和斜体格式化值

        Text {
            id: itemText
            font.pointSize: 24
            text: "<b>" + name + "</b><br><i>" + addr + "</i>"
        }

您的应用程序现在已完成。

另请参阅教程:Qt Quick 调试教程:Qt Widgets 应用程序

©2024 The Qt Company Ltd. 本文档中的文档贡献权归其所有者所有。所提供的文档受GNU自由文档许可证版本1.3的条款约束,由自由软件基金会发布。Qt及其标志是芬兰和其他国家的The Qt Company Ltd.的商标。所有其他商标均为其所有者的财产。