Я хочу испустить сигнал из javascript-файла и получить его в qml-файле (чтобы найти, когда отнимает много времени операция).Как излучать сигналы из javascript в qml
Как я могу это сделать?
Я хочу испустить сигнал из javascript-файла и получить его в qml-файле (чтобы найти, когда отнимает много времени операция).Как излучать сигналы из javascript в qml
Как я могу это сделать?
Ни одно из решений Alex Raja на самом деле не отвечает на вопрос. Alex's состоит в вызове непосредственно из кода javascript метода слотов QML, а Raja заключается в установке значения свойства объекта QML из кода Javascript. Оба подхода отрицают основное преимущество механизма сигнала/слота, которое заключается в том, что сигнальный объект не должен знать о слоте.
Подход ближе к духу механизма сигнала/слота описан в этом blog post (не мой). Он состоит в том, что в файле javascript создается объект QML (через функцию Qt.createQmlObject()
), единственная функция которого состоит в том, чтобы содержать объектные сигналы javascript. Сигналы испускаются из javascript посредством вызова внутреннего сигнала объектов QML (например, internalQmlObject.signalName()
), а сигнал объекта javascript может быть подключен в QML к слотам QML с помощью обычного механизма connect
через javascriptObject.internalQmlObject.signalName.connect(receiver.slotName)
.
Пример заимствован из блога ниже:
javascript_object.js:
var internalQmlObject = Qt.createQmlObject('import QtQuick 2.0; QtObject { signal someSignal(int value) }', Qt.application, 'InternalQmlObject');
function doSomething() {
internalQmlObject.someSignal(42);
}
test.qml:
import QtQuick 2.0
import 'javascript_object.js' as JavascriptObject
Rectangle {
Rectangle {
id: someComponent
function someSlot(v) {
console.log("Signal received " + v);
}
}
Component.onCompleted: {
JavascriptObject.internalQmlObject.someSignal.connect(someComponent.someSlot);
JavascriptObject.doSomething();
}
}
Об исполнении он дает следующее:
% qmlscene test.qml
Signal received 42
QML - это декларирующий язык UI, широко используемый для разработки пользовательского интерфейса. Вы не можете писать слишком много или сложных функций в самом QML. Но вы можете иметь как JavaScript, так и QML в одном файле.
Предположим, что если вы хотите остановить анимацию, например, при загрузке gif-анимации, после трудоемкого процесса просто рассмотрите следующую строку кода.
loadingAnimation.running = false;
Вышеприведенная строка кода может быть вызвана из самого файла JavaScript. Если вы все еще считаете, что этой функции недостаточно, сообщите нам свой случай использования.
спасибо, @RajaVarma.
Я нашел решение для себя.
В qml-file: create element Item (my loginItem), который содержит функцию, которая играет роль слота. Например (я должен знать, когда ручка Войти событие):
import "scripts/auth.js" as Auth
...
Item {
id: loginItem
// Send himself to javascript module named Auth
Component.onCompleted: {
Auth.setLoginItem(loginItem);
}
// "Slot" function
function logged() {
console.debug("Login successfully");
// Do something
...
}
}
В JS-файл: создать приемник для loginItem и использовать его.
var loginItem;
function setLoginItem(tempLoginItem) {
loginItem = tempLoginItem;
}
...
// Emit "signal"
loginItem.logged();
...
не имеет отношения к вопросу, но он «вошел в систему» не «подключен»;) –
Прошу прощения за мой английский. В этом месяце я обещаю продолжить курс. –
Ну, это очень хаки, чтобы вызывать сигналы из реального JS-файла. Но есть лучший вариант, ИМХО, вместо этого использовал его сам. Создайте свой собственный класс.
MyClass.qml
import QtQuick 2.0
QtObject
{
property var myVariable
function myFunction() { console.log("emitting signal"); mySignal() }
signal mySignal
}
Таким образом, вы можете легко достичь необходимой инкапсуляции. И вы можете даже приятно подключиться к объекту.
Тогда вы можете делать с ним все, что хотите: создать из него одноэлементный, создать глобальный объект, создать его экземпляр.
Я согласен. Хорошее решение. –