Вопрос:
У меня есть код QML, например, этот код
Item { id:self; function update(){ var visitFunc = self.applyUpdate; innerTraversal(self,visitFunc); } function reset(){ var visitFunc = self.applyReset; innerTraversal(self,visitFunc); } function innerTraversal(obj, visitFun){ console.log(typeof visitFun); if(obj!== self && visitFun && typeof visitFun ===»function») visitFun(obj); if(hasChilderns(obj)){ var objChilderns = obj.children; for(var i=0 ; i< objChilderns.length ; i++){ innerTraversal(objChilderns[i]); } } } function hasChilderns(obj){ if(typeof obj.children !== ‘undefined’) return true; else return false; } function applyReset(obj){ if(typeof obj.reset === ‘function’) obj.reset(); } function applyUpdate(obj){ if(typeof obj.update === ‘function’) obj.update(); } }
в обычном javascript это работает классно, но когда я использую этот код в QML, то плохая вещь visitFun всегда имеет тип undefined, и это не работает.
любая идея, как сделать эту работу?
Ответ №1
В внутренних функциях QML ваш “я” имеет тип “QQuickItem”, в то время как обычный JS-объект (созданный с помощью “new Object()” или “{” prop “:” value “}”, например, имеет тип QJsValue. И “я” – это не переменное имя, оно QML id, помните о том, что defference.
В QML использование сигналовслотов или привязок свойств может быть гораздо более мощным, чем передача обратного вызова, как в “нормальном” JS. Использование “typeof” также является плохой практикой (насколько я знаю в “нормальном” JS тоже), вы можете просто написать что-то вроде:
// Or simply «return obj.children» — but function become useless than. if(obj.children) return true; else return false;
Но этот код все еще бесполезен – свойство элемента “children” в QML имеет тип “list”, он всегда существует.
Итак, мой вывод – вы должны попробовать изучить некоторые основы QML, прежде чем что-то писать.
Ответ №2
В QtQuick 2 вы сможете привязывать функции к свойствам с помощью
Item { //<— declaration id : item property variant fun } item.fun : Qt.binding(function(){doSomething()}) //<—defintion item.fun // <— invocation without braces
Таким образом, вы можете передать объект с общей функцией в качестве параметра.
В общем случае перегрузка функции a также может использоваться для создания общей функции, например, для создания типа Button:
—Button.qml Item { function fun() {} //<— declaration (empty dummy) MouseArea { anchors.fill: parent onClicked: { fun(); //<— invocation } } } — —main.qml— Button { id: button function fun() { //<— defintion by overloading doSomething } } —
Нажатие кнопки активирует обработчик onClick и фактически что-то делает;). Опять же, вы должны передать объект с общей функцией, а не самой функцией.