跳转到内容

第 3 课:自定义组件 ​

更新: 10/23/2026 字数: 0 字 时长: 0 分钟

现在你的 Main.qml 里所有东西都堆在一个文件里。
如果界面越来越大,会很难维护。QML 的做法是:把可复用的 UI 拆成独立的 .qml 文件。

这一课我们做一个自己的组件:MyButton.qml。

自定义 MyButton ​

第一步:新建文件 ​

在 Qt Creator 里,右键你的项目 → Add New... → 选择 Qt > QML File (Qt Quick 2),文件名填:

text
MyButton.qml

注意:文件名首字母必须大写,这是 QML 组件命名规则。


第二步:写 MyButton.qml ​

把内容替换成:

qml
import QtQuick

Rectangle {
    id: root

    width: 160
    height: 48
    radius: 8
    color: "lightblue"

    property alias text: label.text
    signal clicked

    Text {
        id: label
        anchors.centerIn: parent
        font.pixelSize: 20
        text: "按钮"
    }

    MouseArea {
        anchors.fill: parent
        onClicked: root.clicked()
    }
}

第三步:在 Main.qml 里使用它 ​

把 Main.qml 改成:

qml
import QtQuick
import QtQuick.Window

Window {
    width: 640
    height: 480
    visible: true
    title: "第三课"

    MyButton {
        anchors.centerIn: parent
        text: "点我试试"
        onClicked: console.log("按钮被点击了")
    }
}

运行后,你会看到一个自己做的按钮。点击它,Qt Creator 的 Application Output 面板会打印:

text
按钮被点击了

关键概念讲解 ​

1. 文件名就是组件名 ​

MyButton.qml 这个文件,在同一个目录下的其他 QML 文件里,可以直接当成类型 MyButton 使用。

不需要 import,因为是同目录。

规则:

  • 文件名首字母必须大写
  • 文件名和组件名一致

2. id: root ​

在组件内部,通常给根元素起 id: root,方便内部引用自己。

qml
MouseArea {
    onClicked: root.clicked()
}

这里 root 指向 Rectangle 本身。

3. property alias text: label.text ​

这一行做了两件事:

  1. 给组件暴露一个叫 text 的属性。
  2. 这个属性其实是内部 label.text 的别名。

所以外部可以写:

qml
MyButton {
    text: "点我试试"
}

就相当于设置了内部 Text 的文字。

property alias 常用于把内部元素的属性暴露出去。

4. signal clicked ​

声明一个自定义信号,名字叫 clicked。

qml
signal clicked

然后在 MouseArea 里触发它:

qml
onClicked: root.clicked()

外部就能这样监听:

qml
MyButton {
    onClicked: console.log("按钮被点击了")
}

这就是自定义组件和外部通信的标准方式。

你的动手练习 ​

练习 1 ​

给 MyButton 加一个属性,控制颜色:

qml
property alias bgColor: root.color

然后外部这样用:

qml
MyButton {
    bgColor: "tomato"
    text: "红色按钮"
}

练习 2 ​

在 Main.qml 里放两个 MyButton:

qml
MyButton {
    text: "按钮 A"
    anchors.centerIn: parent
    anchors.verticalCenterOffset: -40
}

MyButton {
    text: "按钮 B"
    anchors.centerIn: parent
    anchors.verticalCenterOffset: 40
    bgColor: "orange"
}

练习 3 ​

点击按钮 A 时,把按钮 B 的文字改掉。

提示:给 B 加 id: btnB,在 A 的 onClicked 里写:

qml
btnB.text = "被 A 改了"

练习 4(思考题) ​

如果我把 MyButton.qml 的文件名改成 myButton.qml,还能用 MyButton { } 吗?为什么?