跳转到内容

第 11 课:Popup、Dialog 和 Menu ​

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

这一课学三类浮层:

  1. Popup:通用弹窗容器
  2. Dialog:带标题和标准按钮的对话框
  3. Menu / MenuItem:菜单

使用 Popup、Dialog 与 Menu 实现弹窗和菜单交互 ​

1. Popup:通用弹窗 ​

Popup 是最基础的浮层,本身没有标题栏和按钮,内容由你放。

qml
import QtQuick
import QtQuick.Controls

ApplicationWindow {
    width: 420
    height: 320
    visible: true
    title: "第十一课"

    Button {
        anchors.centerIn: parent
        text: "打开 Popup"
        onClicked: popup.open()
    }

    Popup {
        id: popup
        anchors.centerIn: parent
        width: 280
        height: 160
        modal: true
        focus: true
        closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside

        background: Rectangle {
            color: "white"
            border.color: "#ccc"
            radius: 8
        }

        Column {
            anchors.centerIn: parent
            spacing: 12

            Label {
                text: "这是一个 Popup"
                font.pixelSize: 20
                anchors.horizontalCenter: parent.horizontalCenter
            }

            Button {
                text: "关闭"
                anchors.horizontalCenter: parent.horizontalCenter
                onClicked: popup.close()
            }
        }
    }
}

常用属性:

  • modal:是否模态,模态时挡住后面交互
  • focus:打开时是否获取焦点
  • closePolicy:关闭策略,可按 Esc、点外部关闭
  • background:背景,默认是一个矩形
  • open() / close():打开和关闭
  • opened / closed:状态信号

Popup 适合做自定义浮层、提示框、下拉面板。


2. Dialog:对话框 ​

Dialog 继承自 Popup,增加了标题、标准按钮、accepted / rejected 信号。

qml
Button {
    anchors.centerIn: parent
    text: "打开 Dialog"
    onClicked: dialog.open()
}

Dialog {
    id: dialog
    anchors.centerIn: parent
    title: "确认"
    modal: true
    standardButtons: Dialog.Ok | Dialog.Cancel

    onAccepted: console.log("点了确定")
    onRejected: console.log("点了取消")

    Label {
        text: "确定要执行这个操作吗?"
    }
}

常用属性:

  • title:标题
  • standardButtons:标准按钮组合,如 Dialog.Ok、Dialog.Cancel、Dialog.Yes、Dialog.No
  • onAccepted:点确定/是时触发
  • onRejected:点取消/否时触发
  • contentItem:内容区,通常直接放子元素

Dialog 适合:确认框、提示框、简单表单。

注意:Qt 6 里 MessageDialog 在 QtQuick.Dialogs 模块里,写法略有不同:

qml
import QtQuick.Dialogs

MessageDialog {
    id: msg
    title: "提示"
    text: "操作完成"
}

初学阶段先用 Dialog 就够了。


3. Menu 和 MenuItem ​

菜单通常配合按钮或右键使用。

qml
Button {
    anchors.centerIn: parent
    text: "打开菜单"
    onClicked: menu.open()

    Menu {
        id: menu
        y: parent.height

        MenuItem {
            text: "新建"
            onTriggered: console.log("新建")
        }
        MenuItem {
            text: "打开"
            onTriggered: console.log("打开")
        }
        MenuSeparator { }
        MenuItem {
            text: "退出"
            onTriggered: Qt.quit()
        }
    }
}

关键点:

  • Menu 里的子项是 MenuItem
  • onTriggered 是菜单项被选中的信号
  • MenuSeparator 是分隔线
  • menu.open() 打开菜单

右键菜单:

qml
MouseArea {
    anchors.fill: parent
    acceptedButtons: Qt.RightButton
    onClicked: contextMenu.popup()

    Menu {
        id: contextMenu
        MenuItem { text: "复制"; onTriggered: console.log("复制") }
        MenuItem { text: "粘贴"; onTriggered: console.log("粘贴") }
    }
}

popup() 会在鼠标位置弹出。


4. 其他常用浮层 ​

  • Drawer:侧边抽屉,常用于移动端菜单
  • ToolTip:悬停提示
  • ToolBar:工具栏
  • TabBar:标签栏

这些都属于 Controls,用法和上面类似,需要时查文档即可。


5. 什么时候用哪个 ​

场景推荐
自定义浮层、提示面板Popup
确认框、带按钮的对话框Dialog
下拉菜单、右键菜单Menu
侧边导航Drawer
鼠标悬停提示ToolTip

你的动手练习 ​

练习 1 ​

做一个删除确认框:

  • 按钮“删除”
  • 点击弹出 Dialog,标题“确认删除”,内容是“删除后不可恢复”
  • 点确定打印“已删除”,点取消打印“已取消”

练习 2 ​

用 Popup 做一个自定义提示框:

  • 显示一条消息
  • 3 秒后自动关闭

提示:Popup 里放一个 Timer:

qml
Timer {
    interval: 3000
    running: popup.opened
    onTriggered: popup.close()
}

练习 3 ​

给第 9 课的水果列表加右键菜单:

  • 右键某一行,弹出菜单
  • 菜单项“删除”,点击删除该行

提示:在 delegate 的 Rectangle 里加 MouseArea,用 contextMenu.popup()。

练习 4(思考题) ​

Popup 的 modal: true 和 modal: false 有什么区别?
如果弹窗是模态的,用户还能点后面的按钮吗?为什么?