2012-01-02 9 views

ответ

6

Ни одно из решений 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 
+0

Я согласен. Хорошее решение. –

0

QML - это декларирующий язык UI, широко используемый для разработки пользовательского интерфейса. Вы не можете писать слишком много или сложных функций в самом QML. Но вы можете иметь как JavaScript, так и QML в одном файле.

Предположим, что если вы хотите остановить анимацию, например, при загрузке gif-анимации, после трудоемкого процесса просто рассмотрите следующую строку кода.

loadingAnimation.running = false; 

Вышеприведенная строка кода может быть вызвана из самого файла JavaScript. Если вы все еще считаете, что этой функции недостаточно, сообщите нам свой случай использования.

3

спасибо, @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(); 
... 
+0

не имеет отношения к вопросу, но он «вошел в систему» ​​не «подключен»;) –

+4

Прошу прощения за мой английский. В этом месяце я обещаю продолжить курс. –

1

Ну, это очень хаки, чтобы вызывать сигналы из реального JS-файла. Но есть лучший вариант, ИМХО, вместо этого использовал его сам. Создайте свой собственный класс.

MyClass.qml

import QtQuick 2.0 

QtObject 
{ 
    property var myVariable 
    function myFunction() { console.log("emitting signal"); mySignal() } 
    signal mySignal 
} 

Таким образом, вы можете легко достичь необходимой инкапсуляции. И вы можете даже приятно подключиться к объекту.

Тогда вы можете делать с ним все, что хотите: создать из него одноэлементный, создать глобальный объект, создать его экземпляр.