Добавить обработчик сигнала в ECMAscript для только что созданного элемента

Я хочу создать MenuItem динамически и добавить для него обратный вызов onTriggered.

var m = backContextMenu.insertItem(0,text) 

m.onTriggered = ..? //function(x) { console.log('asd') }

Выдает ошибку Cannot assign to read-only property "onTriggered". Что я могу сделать? Может быть, мне следует создать свое меню, используя Qt.createQmlObject('qml code...')? Или, может быть, я должен декларативно создать шаблон MenuItem и как-то клонировать этот объект?

P.S. Я использую MenuItem из QtQuick.Controls в Qt 5.2


person Kakadu    schedule 28.09.2013    source источник


Ответы (3)


Вы можете использовать элемент Connections QML для создания динамических соединений с помощью функции createQmlObject:

var item = menuContext.insertItem(0, "menu item")
Qt.createQmlObject("import QtQuick 2.0;Connections{onTriggered:foo()}",item)

Просто вы можете создать также прямое соединение:

item.onTriggered.connect(foo)

(MenuItem обязательно Qt Quick 2 и Qt 5.1)

person gbdivers    schedule 28.09.2013
comment
Вы рекомендуете сгенерировать id для моего пункта меню, сгенерировать приведенный выше код с подходящим телом onTriggered и оценить его с помощью Qt.createQmlObject? Я спрашиваю, потому что не понимаю, как использовать фрагмент кода выше для нескольких целей. - person Kakadu; 28.09.2013
comment
Кроме того, я прочитал, что невозможно назначить идентификатор: qt-project.org/forums/viewthread /6986 - person Kakadu; 28.09.2013
comment
Да, но генерировать id не обязательно. Вы находитесь в функции JS, тогда вы должны создать объект Connections, используя createQmlObject. Но на самом деле вы можете напрямую создать соединение с объектом. Первое сообщение обновлено - person gbdivers; 28.09.2013

Мне посчастливилось найти другой способ для динамического добавления элементов меню: через Instantiator.

Menu {
    id: recentFilesMenu

    Instantiator {
        model: recentFilesModel
        MenuItem {
            text: model.fileName
        }
        onObjectAdded: recentFilesMenu.insertItem(index, object)
        onObjectRemoved: recentFilesMenu.removeItem(object)
    }

    MenuSeparator {
        visible: recentFilesModel.count > 0
    }

    MenuItem {
        text: "Clear menu"
        enabled: recentFilesModel.count > 0
        onTriggered: recentFilesModel.clear()
    }
}
person Kakadu    schedule 30.09.2013

Пример кода все объяснит:

    Menu {
        id: suggestionsMenu
        property var suggestions: []

        Instantiator {
            model: suggestionsMenu.suggestions
            onObjectAdded: suggestionsMenu.insertItem(index, object)
            onObjectRemoved: suggestionsMenu.removeItem(object)
            delegate: MenuItem {
                text: suggestionsMenu.suggestions[index]
                onTriggered: {
                    console.log(index + " : " + suggestionsMenu.suggestions[index])
                }
            }
        }
    }

Теперь в коде вам нужно вызвать только такие 3 строки:

onShowSuggestions: {
   console.log("Showing suggestions")
   console.log(suggestions)

   suggestionsMenu.clear()
   suggestionsMenu.suggestions = []
   suggestionsMenu.suggestions = suggestions
   suggestionsMenu.popup()
}

Ссылки:

Меню QML

Тип экземпляра QML

Статья №1

person Dawid Drozd    schedule 11.03.2017