qt - 在 QML 中添加菜单时出错

标签 qt qml qtquick2

我有以下代码:

import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtQuick.Controls 1.4

ApplicationWindow {
    title: qsTr("Hello World!")
    width: 640
    height: 480
    visible: true

    menuBar: MenuBar {
        id: menuBar
    }

    MouseArea
    {
        anchors.fill: parent
        onClicked: { menuBar.menus.addItem("test") }
    }
}

当我运行它并单击时,会出现以下消息:

qrc:/main.qml:19: TypeError: Property 'addItem' of object [object Object] is not a function

这是为什么?

编辑:从 https://stackoverflow.com/users/24283/timday 获取建议 我这样做了:

import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtQuick.Controls 1.4

ApplicationWindow {
    title: qsTr("Hello World!")
    width: 640
    height: 480
    visible: true

    menuBar: MenuBar
    {
        id: menuBar

        function addMenu(text)
        {
            var newObject = Qt.createQmlObject('import QtQuick.Controls 1.4; Menu { id: test; title: "Test" }',
                menuBar, "dynamicSnippet1");

            newObject.visible = true
        }
    }

    MouseArea
    {
        anchors.fill: parent
        onClicked: { menuBar.addMenu("Test") }
    }
}

但是,我无法显示菜单。

编辑:由于似乎不可能做我想做的事,所以我最终推荐了 timday:

import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtQuick.Controls 1.4

ApplicationWindow {
    title: qsTr("Hello World!")
    width: 640
    height: 480
    visible: true

    menuBar: MenuBar
    {
        id: menuBar

        Menu { id: menu00; visible: false; }
        Menu { id: menu01; visible: false; }
        Menu { id: menu02; visible: false; }
        Menu { id: menu03; visible: false; }
        Menu { id: menu04; visible: false; }
        Menu { id: menu05; visible: false; }
        Menu { id: menu06; visible: false; }
        Menu { id: menu07; visible: false; }
        Menu { id: menu08; visible: false; }
        Menu { id: menu09; visible: false; }
        Menu { id: menu10; visible: false; }
        Menu { id: menu11; visible: false; }
        Menu { id: menu12; visible: false; }
        Menu { id: menu13; visible: false; }
        Menu { id: menu14; visible: false; }
        Menu { id: menu15; visible: false; }
        Menu { id: menu16; visible: false; }
        Menu { id: menu17; visible: false; }
        Menu { id: menu18; visible: false; }
        Menu { id: menu19; visible: false; }

        property variant topMenus: [ menu00, menu01, menu02, menu03, menu04,
                                     menu05, menu06, menu07, menu08, menu09,
                                     menu10, menu11, menu12, menu13, menu14,
                                     menu15, menu16, menu17, menu18, menu19 ]
        property int currMenu: 0

        function addMenu(text)
        {
            if (currMenu == topMenus.length)
                console.log("Index out of range")
            else
            {
                var menu = topMenus[currMenu]
                menu.visible = true
                menu.title = text
                currMenu++
                return menu
            }
        }
    }

    MouseArea
    {
        anchors.fill: parent
        onClicked: { menuBar.addMenu("Test") }
    }
}

最佳答案

您实际上需要在 MenuBar 中有一个 Menu 才能添加 MenuItem。像这样:

import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtQuick.Controls 1.4

ApplicationWindow {
  title: qsTr("Hello World!")
  width: 640
  height: 480
  visible: true

  menuBar: MenuBar {
    id: menuBar
    Menu {
      id: tests
      title: "Tests"
    }
  }

  MouseArea
  {
    anchors.fill: parent
    onClicked: { 
      tests.addItem("Test");
    }
  }
}

这个(使用 Qt5.5.0 的 qmlscene 运行)以栏中的“测试”菜单开始,并在每次单击时向其中添加一个“测试”项(远离菜单栏) )。当然,您必须单击打开菜单才能看到项目。

动态创建菜单有点困难;请参阅 Qt.createQmlObject 或 Qt.createComponent 文档。 (在代码中声明您需要的所有内容可能会更简单,但将它们的 visible 属性连接到任何适当的逻辑)。

更新:正如您在更新的问题中所指出的,我刚刚确认了自己,只需添加动态创建的 Menu 作为 MenuBar< 的子级 似乎不足以让 Menu 显示。我注意到它也不会导致 MenuBarmenus 列表变得更大。不幸的是,附加到 QML 并不容易 lists ,它们与 JavaScript 数组不同。 MenuBar 可能有一些有趣的地方...即使尝试为其分配新的菜单列表或空列表也会导致错误消息。可能值得在 QtJira 中提出更好(或更简单,如果可能的话)动态 MenuBar Menu 项目的问题/请求...但我怀疑任何限制可能源于 Qt 在某些平台上使用 native 菜单,可能会强制使用最小公分母级别的功能。

对于使用最初隐藏的占位符的“B 计划”,这在我的 Linux 系统上很有效:

import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtQuick.Controls 1.4

ApplicationWindow {
  title: qsTr("Hello World!")
  width: 640
  height: 480
  visible: true

  menuBar: MenuBar {
    id: menubar
    Menu {title: "File"}
    Menu {id: testsmenu;title: "Tests";visible: false}
    Menu {title: "Help"}
  }

  MouseArea {
    anchors.fill: parent
    onClicked: { 
      testsmenu.visible=true
      testsmenu.addItem("Test")
    }
  }
}

更一般的一点:我觉得我对任何基于向用户显示一组非常动态的菜单栏菜单的应用程序设计都有些怀疑。菜单用户体验模式的全部要点在于它非常静态,用户的“肌肉内存”让他们可以快速导航……但如果菜单相当随机地出现和消失,那就会崩溃。 (好吧,有些应用程序可能会在几种不同的模式下呈现一组不同的菜单,例如具有编辑/ Debug模式的 IDE,但是使用上面的“Plan B”样式以及 QML 的状态概念和连接菜单可见性是完全可行的应用程序状态)。

关于qt - 在 QML 中添加菜单时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32142565/

相关文章:

c++ - QtWebkit:如何处理自定义协议(protocol)

qt - 如何正确更改TableView的行高?

qt - 如何直接在 QML 文件中监听 QGuiApplication::applicationStateChanged 信号

qt - 如何销毁 QML 中的上下文指针?

python - 在 pyqtgraph 中的 x 轴上显示字符串值

c++ - 如何增加 QNetworkReply::downloadProgress 信号频率?

qt - QAbstractTableModel::columnCount 和/或 QAbstractTableModel::rowCount 中的参数 "QModelIndex &parent"何时有用?

QML矩形不透明度只有颜色

qt - QML- MouseArea中未检测到右键单击

qt - 如何在 QML 中隐藏菜单项