在 QML 中添加菜单时出错 [英] Error adding a Menu in QML

查看:65
本文介绍了在 QML 中添加菜单时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

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") }
    }
}

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

When I run it and click, the following message appears:

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

这是为什么?

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

Getting the advice from https://stackoverflow.com/users/24283/timday I did this:

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") }
    }
}

但是,我无法显示菜单.

However, I cannot get the menu to show.

由于似乎不可能做我想做的事,我最终得到了timday的推荐:

Since it seems impossible to do what I want, I ended up with the recommendation of 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 到.像这样:

You need to actually have a Menu to your MenuBar to add MenuItems to. Like this:

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 运行)以栏中的Tests"Menu 开始,每次点击时(远离菜单栏)添加一个Test"项).你必须点击打开菜单才能看到项目.

This (run with Qt5.5.0's qmlscene) starts with a "Tests" Menu in the bar, and adds a "Test" item to it every time you click (away from the menubar). You have to click to open the menu to see the items of course.

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

Dynamic creation of Menus is a little harder; see Qt.createQmlObject or Qt.createComponent docs. (It may be simpler to just declare all the ones you need in your code, but with their visible property wired to whatever logic is appropriate).

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

Update: as you note in your updated question, and I've just confirmed myself, simply adding a dynamically created Menu as a child of MenuBar seems to be insufficient to get the Menu to appear. I note it also doesn't result in the MenuBar's menus list getting any bigger. Unfortunately it's not easy to append to QML lists, they're different from JavaScript arrays. And there may be something funny about MenuBar... even attempting to assign a new list of menus, or an empty list, to it results in an error message. Might be worth raising an issue/request for better (or easier, if it is possible somehow) dynamic MenuBar Menu item in the QtJira... but I suspect any restrictions may arise from Qt's use of native menus on some platforms, forcing least-common-denominator levels of functionality maybe.

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

For a "Plan B" using initially hidden placeholders, this works sensibly on my Linux system:

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")
    }
  }
}

更一般的观点:我觉得我有点怀疑任何基于具有一组非常动态的菜单栏菜单来向用户显示的应用程序设计.菜单 UX 模式的全部要点在于它非常静态,用户的肌肉记忆"让他们可以快速导航……但是如果菜单相当随机地来来去去,那将会中断.(好吧,某些应用程序可能会在几种不同的模式下显示一组不同的菜单,例如具有编辑/调试模式的 IDE,但是使用上面的Plan B"样式和 QML 的状态概念和接线菜单可见性是完全可行的应用状态).

More general point: it occurs to me I'm slightly suspicious of any application design which is predicated on having a very dynamic set of menu bar menus to show the user. Sort of the whole point of the menu UX pattern is that it's pretty static and users' "muscle memory" lets them navigate it fast... but if menus are fairly randomly coming and going that'll break. (OK some applications might present a different set of menus in a couple of different modes e.g IDEs with edit/debug modes, but that'd be quite doable with the "Plan B" style above and QML's notion of states and wiring menu visibility to application state).

这篇关于在 QML 中添加菜单时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆