我有以下代码:
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") }
}
}
答案 0 :(得分:2)
您需要Menu
向MenuBar
添加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");
}
}
}
。像这样:
Menu
这个(使用Qt5.5.0的qmlscene运行)以条形图中的“测试”Menu
开始,并在每次单击(远离菜单栏)时向其添加“测试”项。您必须单击才能打开菜单以查看项目。
Qt.createQmlObject
的动态创建有点困难;请参阅Qt.createComponent
或visible
文档。 (在代码中声明所需的所有内容可能更简单,但将Menu
属性连接到适当的逻辑上。)
更新:正如您在更新的问题中所述,我刚刚确认了自己,只需添加一个动态创建的MenuBar
作为Menu
的孩子似乎是不足以让MenuBar
出现。我注意到它也不会导致menus
的{{1}}列表变得更大。不幸的是,附加到QML lists并不容易,它们与JavaScript数组不同。 MenuBar可能有些有趣......即使尝试为其分配新的菜单列表或空列表也会导致错误消息。可能值得提出一个问题/请求更好(或更容易,如果有可能的话)QtJira中的动态MenuBar
Menu
项......但我怀疑Qt使用本机可能会产生任何限制某些平台上的菜单,可能会强制实现最小公分母级别的功能。
对于使用最初隐藏占位符的“Plan 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")
}
}
}
更一般的观点:它发生在我身上我对任何应用程序设计都有点怀疑,这个应用程序设计的前提是有一组非常动态的菜单栏菜单来向用户显示。菜单UX模式的整个点是它非常静态,用户的“肌肉记忆”让它们快速导航......但是如果菜单是随机进出那么会破坏。 (好的一些应用程序可能会在几种不同的模式下呈现不同的菜单集,例如具有编辑/调试模式的IDE,但是对于上面的“Plan B”风格和QML的状态概念和布线菜单可见性来说,这是非常可行的。申请状态。)
答案 1 :(得分:0)
我找到了解决“显示”问题的方法。在MenuBarPrivate中进行挖掘使我有了使用menusChanged()信号的想法,并且它确实有效。
Menu {
id: foo
...
}
MenuBar {
Component.onCompleted: {
menus.push(foo)
menusChanged()
}
}