本页内容

Menu QML Type

可作为上下文菜单或弹出菜单使用的菜单弹出窗口。更多...

Import Statement: import QtQuick.Controls
Inherits:

Popup

属性

方法

  • Action actionAt(int index) (since QtQuick.Controls 2.3 (Qt 5.10))
  • void addAction(Action action) (since QtQuick.Controls 2.3 (Qt 5.10))
  • void addItem(Item item)
  • void addMenu(Menu menu) (since QtQuick.Controls 2.3 (Qt 5.10))
  • void dismiss() (since QtQuick.Controls 2.3 (Qt 5.10))
  • void insertAction(int index, Action action) (since QtQuick.Controls 2.3 (Qt 5.10))
  • void insertItem(int index, Item item)
  • void insertMenu(int index, Menu menu) (since QtQuick.Controls 2.3 (Qt 5.10))
  • Item itemAt(int index)
  • Menu menuAt(int index) (since QtQuick.Controls 2.3 (Qt 5.10))
  • void moveItem(int from, int to)
  • void popup(MenuItem item) (since QtQuick.Controls 2.3 (Qt 5.10))
  • void popup(Item parent, MenuItem item) (since QtQuick.Controls 2.3 (Qt 5.10))
  • void popup(point pos, MenuItem item) (since QtQuick.Controls 2.3 (Qt 5.10))
  • void popup(Item parent, point pos, MenuItem item) (since QtQuick.Controls 2.3 (Qt 5.10))
  • void popup(real x, real y, MenuItem item) (since QtQuick.Controls 2.3 (Qt 5.10))
  • void popup(Item parent, real x, real y, MenuItem item) (since QtQuick.Controls 2.3 (Qt 5.10))
  • void removeAction(Action action) (since QtQuick.Controls 2.3 (Qt 5.10))
  • void removeItem(Item item) (since QtQuick.Controls 2.3 (Qt 5.10))
  • void removeMenu(Menu menu) (since QtQuick.Controls 2.3 (Qt 5.10))
  • Action takeAction(int index) (since QtQuick.Controls 2.3 (Qt 5.10))
  • MenuItem takeItem(int index) (since QtQuick.Controls 2.3 (Qt 5.10))
  • Menu takeMenu(int index) (since QtQuick.Controls 2.3 (Qt 5.10))

详细说明

采用原生风格的“新建”、“打开”、“保存”菜单

原生 macOS 菜单。

采用“Material”风格的“新建”、“打开”、“保存”菜单

非原生的Material 风格菜单。

菜单主要有两种使用场景:

  • 上下文菜单;例如,右键单击后显示的菜单
  • 弹出菜单;例如,点击按钮后显示的菜单

关于上下文菜单,请参阅Context Menus 。

当用作弹出菜单时,最简便的方法是通过相应属性指定所需的x 和y 坐标来设定位置,并调用open()来打开菜单。

Button {
    id: fileButton
    text: "File"
    onClicked: menu.open()

    Menu {
        id: menu
        y: fileButton.height

        MenuItem {
            text: "New..."
        }
        MenuItem {
            text: "Open..."
        }
        MenuItem {
            text: "Save"
        }
    }
}

如果希望点击按钮时同时关闭菜单,请使用Popup.CloseOnPressOutsideParent 标志:

    onClicked: menu.visible = !menu.visible

    Menu {
        id: menu
        // ...
        closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent

您可以在 Menu 中创建子菜单并声明 Action 对象:

Menu {
    Action { text: "Cut" }
    Action { text: "Copy" }
    Action { text: "Paste" }

    MenuSeparator { }

    Menu {
        title: "Find/Replace"
        Action { text: "Find Next" }
        Action { text: "Find Previous" }
        Action { text: "Replace" }
    }
}

在具备鼠标光标的桌面平台上,子菜单默认处于cascading 状态。非级联菜单每次仅显示一个,并居中显示在父菜单上方。

通常,菜单项会作为菜单的子项静态声明,但 Menu 还提供了 API 来动态创建add 、insert 、move 和remove 项。可通过itemAt() 或contentChildren 访问菜单中的项。

尽管MenuItems 是“菜单”中最常用的项目,但菜单中可以包含任何类型的项目。

上下文菜单

对于上下文菜单,使用ContextMenu 附加类型更为便捷,该类型会在发生特定于平台的事件时创建菜单。此外,诸如TextField 、TextArea 、SpinBox 和DoubleSpinBox 等文本编辑控件默认会提供各自的上下文菜单。

如果不使用 `ContextMenu`,打开菜单的推荐方法是调用 `popup()`。除非显式指定了位置,否则在具有鼠标光标的桌面平台上,菜单将定位在鼠标光标处;否则,菜单将居中显示在其父项上方:

    TapHandler {
        acceptedButtons: Qt.RightButton
        onPressedChanged: {
            if (pressed && Application.styleHints.contextMenuTrigger === Qt.ContextMenuTrigger.Press)
                contextMenu.popup()
        }
        onTapped: {
            if (Application.styleHints.contextMenuTrigger === Qt.ContextMenuTrigger.Release)
                contextMenu.popup()
        }
    }
    TapHandler {
        acceptedDevices: PointerDevice.TouchScreen
        onLongPressed: contextMenu.popup()
    }

    Menu {
        id: contextMenu

        MenuItem {
            text: qsTr("Do stuff")
        }
        MenuItem {
            text: qsTr("Do more stuff")
        }
    }

请注意,如果您正在为文本编辑控件实现自定义右键菜单,则只需在桌面平台上显示该菜单,因为 iOS 和 Android 系统已自带原生右键菜单:

    TextArea {
        text: qsTr("TextArea")

        // Disable the built-in context menu (since Qt 6.9).
        ContextMenu.menu: null

        TapHandler {
            acceptedButtons: Qt.RightButton
            onPressedChanged: {
                if (pressed === (Application.styleHints.contextMenuTrigger === Qt.ContextMenuTrigger.Press))
                    contextMenu.popup()
            }
        }
    }

    Menu {
        id: contextMenu

        MenuItem {
            text: qsTr("Cut")
            // ...
        }
        MenuItem {
            text: qsTr("Copy")
            // ...
        }
        MenuItem {
            text: qsTr("Paste")
            // ...
        }
    }

边距

由于继承自 Popup,Menu 支持 `margins`。默认情况下,所有内置样式都将 Menu 的边距设置为 `0 `,以确保菜单始终位于窗口边界内。若要允许菜单超出窗口范围(例如,为了实现菜单滑入视图的动画效果),请将 `margins` 属性设置为 `-1`。

动态生成菜单项

您可以使用 `Instantiator ` 或动态对象创建来动态生成菜单项。

使用 Instantiator

您可以使用Instantiator 动态生成菜单项。以下代码演示了如何实现“最近文件”子菜单,其中菜单项来源于存储在设置中的文件列表:

Menu {
    title: qsTr("File")

    Menu {
        id: recentFilesMenu
        title: qsTr("Recent Files")
        enabled: recentFilesInstantiator.count > 0

        Instantiator {
            id: recentFilesInstantiator
            model: settings.recentFiles
            delegate: MenuItem {
                text: settings.displayableFilePath(modelData)
                onTriggered: loadFile(modelData)
            }

            onObjectAdded: (index, object) => recentFilesMenu.insertItem(index, object)
            onObjectRemoved: (index, object) => recentFilesMenu.removeItem(object)
        }

        MenuSeparator {}

        MenuItem {
            text: qsTr("Clear Recent Files")
            onTriggered: settings.clearRecentFiles()
        }
    }
}

使用动态对象创建

您还可以使用Qt.createComponent()从QML文件中动态加载组件。组件准备就绪后,可调用其createObject()方法来创建该组件的实例。

Row {
    anchors.centerIn: parent

    Component {
        id: menuItemComponent

        MenuItem {}
    }

    Button {
        id: button
        text: "Menu"
        onClicked: menu.open()
        Menu {
            id: menu
        }
    }

    Button {
        text: "Add item"
        onClicked: {
            onClicked: {
                let menuItem = menuItemComponent.createObject(
                    menu.contentItem, { text: qsTr("New item") })
                menu.addItem(menuItem)
            }
        }
    }
}

自 Qt 6.8 起,菜单根据平台不同提供了三种不同的实现方式。您可以通过设置 `popupType` 来选择优先使用的实现方式。这将让您控制菜单应以独立窗口、父窗口内的项目,还是原生菜单的形式显示。有关这些选项的更多信息,请参阅here 。

popupType 的默认值由样式决定。例如,macOS 样式将其设置为Popup.Native ,而Imagine 样式则使用Popup.Window (当样式未设置弹出类型时,此为默认值)。 如果您对菜单进行了自定义设置,并希望这些设置在任何样式下均生效,则应显式将弹出类型设置为Popup.Window (或Popup.Item )。另一种方法是设置Qt::AA_DontUseNativeMenuWindows application attribute 。这将禁用整个应用程序的原生上下文菜单,无论采用何种样式。

菜单能否使用首选类型取决于平台。Popup.Item 在所有平台上均受支持,但Popup.Window 通常仅在桌面平台上受支持。此外,如果菜单位于native menubar 内,该菜单也将采用原生样式。如果菜单是另一个菜单内的子菜单,则由父(或根)菜单决定其类型。

使用原生菜单时的限制

将popupType 设置为Popup.Native 时,与使用Popup.Item 和Popup.Window 相比,存在一些限制和差异。

API 差异

使用原生菜单时,所有平台仅支持 Menu API 的子集:

此外,在某些平台上,显示弹出窗口(例如使用open() 或popup()) 将会成为阻塞调用。这意味着在菜单再次关闭之前,该调用不会返回,这可能会影响应用程序的逻辑。 如果您的应用程序面向多个平台,并且因此有时会在不支持原生菜单的平台上运行,这一点尤其需要考虑。在这种情况下,popupType 将回退为Popup.Item 等,对open() 的调用将不会阻塞。

例如,MenuItem 之类的项仍会通过发出信号等方式对相应原生菜单项的点击做出反应,但会被其原生对应项所取代。

渲染差异

原生菜单是利用平台上可用的原生菜单 API 实现的。 因此,这些菜单及其所有内容都将由平台渲染,而不是由 QML 渲染。这意味着delegate 不会用于渲染。但是,它始终会被实例化(但处于隐藏状态),因此诸如onCompleted() 之类的函数会无论平台如何都会执行,而popupType则不会。

支持的平台

原生菜单目前在以下平台上受支持:

  • Android
  • iOS
  • Linux(仅在使用 GTK+ 平台主题时,可作为独立的上下文菜单使用)
  • macOS
  • Windows

另请参阅 “自定义菜单”(MenuItem )、“菜单控件”、“弹出控件”、“通过 JavaScript 动态创建 QML 对象”(Popup type )、[QML] 以及popupType 。

属性文档

cascade : bool [since QtQuick.Controls 2.3 (Qt 5.10)]

该属性控制菜单是否以层叠方式显示其子菜单。

默认值因平台而异。在具备鼠标光标的桌面平台上,菜单默认采用级联显示。非级联菜单则一次仅显示一个,并居中显示在父菜单上方。

注意: 在菜单打开期间,更改 该属性的值不会产生任何效果。

注意: 仅在使用non-native Menu 时才支持此 属性。

该属性在 QtQuick.Controls 2.3(Qt 5.10)中引入。

另请参阅 overlap 。

contentData : list<QtObject> [default]

该属性保存内容数据的列表。

该列表包含所有在 QML 中被声明为菜单子节点的对象,以及分别通过addItem() 和insertItem() 方法动态添加或插入的项目。

注意:与 ` contentChildren`不同, `contentData ` 确实包含非可视化 QML 对象。当项目被插入或移动时,该列表不会被重新排序。

另请参阅 Item::data 和contentChildren 。

contentModel : model [read-only]

该属性存储用于显示菜单项的模型。

内容模型用于可视化目的。它可被指定为内容项的模型,以呈现菜单的内容。

Menu {
    id: menu
    contentItem: ListView {
        model: menu.contentModel
    }
}

该模型允许将菜单项静态声明为菜单的子项。

count : int [read-only, since QtQuick.Controls 2.3 (Qt 5.10)]

该属性存储项目数量。

该属性在 QtQuick.Controls 2.3(Qt 5.10)中引入。

currentIndex : int [since QtQuick.Controls 2.3 (Qt 5.10)]

该属性存储当前选中项的索引。

菜单项可通过鼠标悬停或键盘导航进行高亮显示。

注意: 仅在使用non-native Menu 时才支持此 属性。

该属性在 QtQuick.Controls 2.3(Qt 5.10)中引入。

另请参阅 MenuItem::highlighted 。

delegate : Component [since QtQuick.Controls 2.3 (Qt 5.10)]

该属性包含用于创建用于呈现操作的项的组件。

Menu {
    Action { text: "Cut" }
    Action { text: "Copy" }
    Action { text: "Paste" }
}

注意: 仅在使用non-native Menu 时,委托 才会可见。

菜单不会拥有该委托的所有权。

该属性在 QtQuick.Controls 2.3(Qt 5.10)中引入。

另请参阅 Action 。

focus : bool

该属性用于指定弹出窗口是否希望获得焦点。

当弹出窗口实际获得焦点时,activeFocus 将变为true 。有关更多信息,请参阅 Qt Quick 中的“键盘焦点”部分。

默认值为true 。

注意: 仅在使用 `non-native Menu` 时才支持此 属性。

另请参阅 activeFocus 。

icon group

icon.cache : bool [since QtQuick.Controls 6.5]

icon.color : color [since QtQuick.Controls 6.5]

icon.height : int [since QtQuick.Controls 6.5]

icon.name : string [since QtQuick.Controls 6.5]

icon.source : url [since QtQuick.Controls 6.5]

icon.width : int [since QtQuick.Controls 6.5]

名称描述
名称此属性用于指定要使用的图标名称。

图标将从平台主题中加载。如果在主题中找到了该图标,则始终使用该图标;即使同时设置了icon.source ,也是如此。如果未找到该图标,则改用icon.source 。

有关主题图标的更多信息,请参阅QIcon::fromTheme()。

source此属性用于指定要使用的图标名称。

该图标将作为普通图像加载。

如果设置了icon.name 且其指向一个有效的主题图标,则系统将始终使用该图标,而非此属性。

width此属性用于指定图标的宽度。

图标的宽度绝不会超过此值,但在必要时会缩小。

height此属性用于指定图标的高度。

图标的高度绝不会超过此值,但在必要时会缩小。

颜色此属性用于指定图标颜色。

图标将采用指定的颜色进行着色,除非该颜色被设置为"transparent" 。

缓存此属性指定是否应将图标缓存。

默认值为 true。

有关更多信息,请参阅cache 。

该属性自QtQuick.Controls 2.13 起引入。

注意: 仅在使用non-native Menu 时才支持此 属性。

这些属性是在 QtQuick.Controls 6.5 中引入的。

另请参阅 AbstractButton::text 、AbstractButton::display 以及 Qt Quick Controls 中的图标。

overlap : real [since QtQuick.Controls 2.3 (Qt 5.10)]

该属性指定菜单在水平方向上与父菜单重叠的像素数。

仅当菜单用作级联子菜单时,该属性才生效。

默认值因样式而异。

注意: 在菜单打开时,更改 该属性的值不会产生任何效果。

注意: 仅在使用non-native Menu 时才支持此 属性。

该属性在 QtQuick.Controls 2.3(Qt 5.10)中引入。

另请参阅 cascade 。

separatorsCollapsible : bool [since QtQuick.Controls 6.12 (Qt 6.12)]

此属性控制是否应折叠连续的分隔符。

当此属性设置为true 时,菜单会自动隐藏可能出现在可见项目开头或结尾的分隔符,以及那些其间所有项目均被隐藏的连续分隔符。这与Qt Widgets 中QMenu::separatorsCollapsible 的行为一致。

默认值为true 。

当菜单项动态显示或隐藏时,此功能非常有用,因为它可防止孤立的分隔符被显示出来。

注意: 在visible 属性上具有用户定义绑定的分隔符 不受此机制影响,将保持不变。对于没有visible 绑定的分隔符,菜单将同时管理visible 和height 属性。height 上任何现有的绑定都将被覆盖。

该属性在 QtQuick.Controls 6.12(Qt 6.12)中引入。

另请参阅 MenuSeparator 。

title : string

该属性用于存储菜单的标题。

当菜单为子菜单时,其标题通常显示在菜单项的文本中;当菜单位于菜单栏中时,其标题则显示在工具按钮的文本中。

方法文档

[since QtQuick.Controls 2.3 (Qt 5.10)] Action actionAt(int index)

返回index 处的操作;如果索引无效或指定索引处没有操作,则返回null 。

该方法于 QtQuick.Controls 2.3(Qt 5.10)中引入。

[since QtQuick.Controls 2.3 (Qt 5.10)] void addAction(Action action)

将action 添加到此菜单的末尾。该菜单不会获取新添加的action 的所有权。

该方法于 QtQuick.Controls 2.3(Qt 5.10)中引入。

void addItem(Item item)

将item 添加到项目列表的末尾。该菜单不会获取新添加的item 的所有权。

另请参阅 Dynamically Generating Menu Items 。

[since QtQuick.Controls 2.3 (Qt 5.10)] void addMenu(Menu menu)

将menu 作为子菜单添加到该菜单的末尾。该菜单不会获取新添加的menu 的所有权。

该方法于 QtQuick.Controls 2.3(Qt 5.10)中引入。

[since QtQuick.Controls 2.3 (Qt 5.10)] void dismiss()

关闭该菜单所属层次结构中的所有菜单。

注意:与仅 关闭菜单及其子菜单的close()不同 (当使用non-native menus 时),dismiss() 会关闭整个菜单层次结构,包括父菜单。实际上,close() 适用于实现菜单层次结构中的导航,而dismiss() 则是关闭整个菜单层次结构的合适方法。

该方法于 QtQuick.Controls 2.3(Qt 5.10)中引入。

另请参阅 popup() 和Popup::close()。

[since QtQuick.Controls 2.3 (Qt 5.10)] void insertAction(int index, Action action)

在index 处插入action 。该索引位于菜单中的所有项目之内。菜单不会获取新插入的action 的所有权。

该方法于 QtQuick.Controls 2.3(Qt 5.10)中引入。

void insertItem(int index, Item item)

在index 处插入item 。该菜单不会获取新插入的item 的所有权。

另请参阅 Dynamically Generating Menu Items 。

[since QtQuick.Controls 2.3 (Qt 5.10)] void insertMenu(int index, Menu menu)

将menu 作为子菜单插入到index 中。该索引位于菜单中的所有项目之中。菜单不会获取新插入的menu 的所有权。

此方法于 QtQuick.Controls 2.3(Qt 5.10)中引入。

Item itemAt(int index)

返回位于index 的项目;如果不存在,则返回null 。

返回索引为index 处的子菜单;如果索引无效或指定索引处不存在子菜单,则返回null 。

该方法于 QtQuick.Controls 2.3(Qt 5.10)中引入。

void moveItem(int from, int to)

将一个项目from 移动一个索引to 另一个索引。

在具备鼠标光标的桌面平台上,在鼠标光标位置打开菜单;否则,将菜单居中显示在其“parent ”项目上方。

可选地,将菜单对齐到特定的菜单item 。此时,该项将变为current. 。如果未指定item ,则currentIndex 将被设置为-1 。

这些方法在 QtQuick.Controls 2.3(Qt 5.10)中引入。

另请参阅 Popup::open()。

在弹出窗口坐标系中,于指定位置pos 处打开菜单,即相对于其parent 项的坐标。

可选地,将菜单对齐到特定的菜单item 。此时该项将变为current. 。如果未指定item ,则currentIndex 将被设置为-1 。

这些方法在 QtQuick.Controls 2.3(Qt 5.10)中引入。

另请参阅 Popup::open()。

在弹出窗口坐标系中,于指定位置x 、y 处打开菜单,即相对于其parent 项的坐标。

该菜单可选地对齐到特定的菜单item 。此时,该项将变为current. 。如果未指定item ,则currentIndex 将被设置为-1 。

这些方法在 QtQuick.Controls 2.3(Qt 5.10)中引入。

另请参阅 dismiss() 和Popup::open()。

[since QtQuick.Controls 2.3 (Qt 5.10)] void removeAction(Action action)

移除并销毁指定的action 。

该方法于 QtQuick.Controls 2.3(Qt 5.10)中引入。

[since QtQuick.Controls 2.3 (Qt 5.10)] void removeItem(Item item)

移除并销毁指定的item 。

该方法于 QtQuick.Controls 2.3(Qt 5.10)中引入。

[since QtQuick.Controls 2.3 (Qt 5.10)] void removeMenu(Menu menu)

移除并销毁指定的menu 。

该方法于 QtQuick.Controls 2.3(Qt 5.10)中引入。

[since QtQuick.Controls 2.3 (Qt 5.10)] Action takeAction(int index)

移除并返回位于index 处的操作。该索引属于菜单中的所有项目。

注意: 该操作的所有权将转移给调用方。

此方法自 QtQuick.Controls 2.3(Qt 5.10)起引入。

[since QtQuick.Controls 2.3 (Qt 5.10)] MenuItem takeItem(int index)

移除并返回位于index 处的项。

注意: 该项的所有 权将转移给调用方。

该方法于 QtQuick.Controls 2.3(Qt 5.10)中引入。

[since QtQuick.Controls 2.3 (Qt 5.10)] Menu takeMenu(int index)

移除并返回位于index 处的菜单。该索引包含在菜单中的所有项目内。

注意: 菜单的所有 权将转移给调用方。

此方法于 QtQuick.Controls 2.3(Qt 5.10)中引入。

© 2026 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.