Ошибка добавления меню в 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") }
}
}
Когда я запускаю его и нажимаю, появляется следующее сообщение:
qrc:/main.qml:19: TypeError: Property 'addItem' of object [object Object] is not a function
Почему это?
РЕДАКТИРОВАТЬ: получить совет от 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") }
}
}
Тем не менее, я не могу получить меню, чтобы показать.
РЕДАКТИРОВАТЬ: Поскольку кажется невозможным делать то, что я хочу, я закончил с рекомендацией Тимдей:
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") }
}
}
1 ответ
Вы должны на самом деле иметь 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");
}
}
}
Это (запуск с qmlscene Qt5.5.0) начинается с "Тестов" Menu
в панели, и добавляет элемент "Тест" к нему каждый раз, когда вы нажимаете (вдали от строки меню). Вы должны нажать, чтобы открыть меню, чтобы увидеть элементы, конечно.
Динамическое создание Menu
с немного сложнее; увидеть Qt.createQmlObject
или же Qt.createComponent
Docs. (Может быть проще просто объявить все, что вам нужно в вашем коде, но с их visible
свойство привязано к какой-либо логике).
Обновление: как вы отметили в своем обновленном вопросе, и я только что подтвердил, просто добавив динамически созданный Menu
как ребенок MenuBar
кажется недостаточным, чтобы получить Menu
появляться. Я отмечаю, что это также не приводит к MenuBar
"s menus
список становится больше. К сожалению, нелегко добавить в списки QML, они отличаются от массивов JavaScript. И в MenuBar может быть что-то смешное... даже попытка назначить ему новый список меню или пустой список приводит к сообщению об ошибке. Возможно, стоит поднять вопрос / запрос на лучшую (или более легкую, если возможно, каким-либо образом) динамическую MenuBar
Menu
элемент в QtJira... но я подозреваю, что любые ограничения могут возникнуть из-за использования Qt нативных меню на некоторых платформах, возможно, для навязывания уровней функциональности с наименьшим общим знаменателем.
Для "Плана 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 с режимами редактирования / отладки, но это вполне выполнимо с использованием приведенного выше стиля "План Б" и представления состояний QML и видимости меню проводки для состояние приложения).
Нашел решение проблемы "показа". Копание в MenuBarPrivate натолкнуло меня на идею использовать сигнал menusChanged(), и он действительно работает.
Menu {
id: foo
...
}
MenuBar {
Component.onCompleted: {
menus.push(foo)
menusChanged()
}
}