第 11 课:Popup、Dialog 和 Menu
更新: 10/23/2026 字数: 0 字 时长: 0 分钟
这一课学三类浮层:
Popup:通用弹窗容器Dialog:带标题和标准按钮的对话框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.NoonAccepted:点确定/是时触发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里的子项是MenuItemonTriggered是菜单项被选中的信号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 有什么区别?
如果弹窗是模态的,用户还能点后面的按钮吗?为什么?