En esta página

Expresiones JavaScript en documentos QML

El entorno de host JavaScript proporcionado por QML puede ejecutar construcciones JavaScript estándar válidas, como operadores condicionales, matrices, establecimiento de variables y bucles. Además de las propiedades estándar de JavaScript, el objeto global QML incluye una serie de métodos de ayuda que simplifican la creación de interfaces de usuario y la interacción con el entorno QML.

El entorno JavaScript proporcionado por QML es más estricto que el de un navegador web. Por ejemplo, en QML no se pueden añadir ni modificar miembros del objeto global de JavaScript. En JavaScript normal, es posible hacerlo accidentalmente utilizando una variable sin declararla. En QML, esto provocará una excepción, por lo que todas las variables locales deben declararse explícitamente. Consulte Restricciones del entorno JavaScript para obtener una descripción completa de las restricciones del código JavaScript ejecutado desde QML.

Varias partes de los documentos QML pueden contener código JavaScript:

  1. El cuerpo de los enlaces de propiedades. Estas expresiones de JavaScript describen relaciones entre propiedades de objetos QML. Cuando las dependencias de una propiedad cambian, la propiedad también se actualiza automáticamente, de acuerdo con la relación especificada.
  2. El cuerpo de los manejadores de señales. Estas expresiones de JavaScript se evalúan automáticamente cada vez que un objeto QML emite la señal asociada.
  3. La definición de métodos personalizados. Las funciones JavaScript que se definen dentro del cuerpo de un objeto QML se convierten en métodos de dicho objeto.
  4. Archivos de recursos JavaScript independientes (.js). En realidad, estos archivos son independientes de los documentos QML, pero pueden importarse en documentos QML. Las funciones y variables definidas en los archivos importados pueden utilizarse en enlaces de propiedades, controladores de señales y métodos personalizados.

JavaScript en los enlaces de propiedades

En el ejemplo siguiente, la propiedad color de Rectangle depende de la propiedad pressed de TapHandler. Esta relación se describe mediante una expresión condicional:

import QtQuick 2.12

Rectangle {
    id: colorbutton
    width: 200; height: 80;

    color: inputHandler.pressed ? "steelblue" : "lightsteelblue"

    TapHandler {
        id: inputHandler
    }
}

De hecho, cualquier expresión de JavaScript (por compleja que sea) puede utilizarse en una definición de vinculación de propiedades, siempre que el resultado de la expresión sea un valor cuyo tipo pueda asignarse a la propiedad. Esto incluye los efectos secundarios. Sin embargo, se desaconsejan los enlaces complejos y los efectos secundarios porque pueden reducir el rendimiento, la legibilidad y la facilidad de mantenimiento del código.

Hay dos formas de definir un enlace de propiedad: la más común se muestra en el ejemplo anterior, en una inicialización de propiedad. La segunda (y mucho más rara) es asignar a la propiedad una función devuelta por la función Qt.binding(), desde dentro de código JavaScript imperativo, como se muestra a continuación:

import QtQuick 2.12

Rectangle {
    id: colorbutton
    width: 200; height: 80;

    color: "red"

    TapHandler {
        id: inputHandler
    }

    Component.onCompleted: {
        color = Qt.binding(function() { return inputHandler.pressed ? "steelblue" : "lightsteelblue" });
    }
}

Consulte la documentación sobre enlaces de propiedades para obtener más información sobre cómo definir enlaces de propiedades, y consulte la documentación sobre Asignación de propiedades frente a Enlace de propiedades para obtener información sobre en qué se diferencian los enlaces de las asignaciones de valores.

JavaScript en manejadores de señales

Los tipos de objeto QML pueden emitir señales como reacción a determinados eventos. Estas señales pueden gestionarse mediante funciones de controladores de señales, que los clientes pueden definir para implementar lógica de programa personalizada.

Supongamos que un botón representado por un tipo Rectángulo tiene una etiqueta TapHandler y una etiqueta Texto. El TapHandler emite su señal tapped cuando el usuario pulsa el botón. Los clientes pueden reaccionar a la señal en el manejador onTapped utilizando expresiones JavaScript. El motor QML ejecuta estas expresiones JavaScript definidas en el manejador según sea necesario. Normalmente, un manejador de señales está vinculado a expresiones JavaScript para iniciar otros eventos o asignar valores de propiedades.

import QtQuick 2.12

Rectangle {
    id: button
    width: 200; height: 80; color: "lightsteelblue"

    TapHandler {
        id: inputHandler
        onTapped: {
            // arbitrary JavaScript expression
            console.log("Tapped!")
        }
    }

    Text {
        id: label
        anchors.centerIn: parent
        text: inputHandler.pressed ? "Pressed!" : "Press here!"
    }
}

Para obtener más información sobre las señales y los controladores de señales, consulte los temas siguientes:

JavaScript en funciones independientes

La lógica del programa también se puede definir en funciones JavaScript. Estas funciones pueden definirse en línea en documentos QML (como métodos personalizados) o externamente en archivos JavaScript importados.

JavaScript en métodos personalizados

Los métodos personalizados pueden definirse en documentos QML y pueden llamarse desde controladores de señales, vinculaciones de propiedades o funciones de otros objetos QML. Estos métodos suelen denominarse funciones JavaScript en línea porque su implementación se incluye en la definición del tipo de objeto QML (documento QML), en lugar de en un archivo JavaScript externo.

Un ejemplo de método personalizado en línea es el siguiente:

import QtQuick 2.12

Item {
    function fibonacci(n){
        var arr = [0, 1];
        for (var i = 2; i < n + 1; i++)
            arr.push(arr[i - 2] + arr[i -1]);

        return arr;
    }
    TapHandler {
        onTapped: console.log(fibonacci(10))
    }
}

La función fibonacci se ejecuta siempre que TapHandler emite una señal tapped.

Nota: los métodos personalizados definidos en línea en un documento QML están expuestos a otros objetos y, por lo tanto, las funciones en línea del objeto raíz de un componente QML pueden ser invocadas por personas ajenas al componente. Si no se desea esto, el método puede añadirse a un objeto no raíz o, preferiblemente, escribirse en un archivo JavaScript externo.

Consulte la documentación Atributos de objeto QML para obtener más información sobre la definición de métodos personalizados en QML mediante JavaScript.

Funciones definidas en un archivo JavaScript

La lógica de programa no trivial se separa mejor en un archivo JavaScript independiente. Este archivo puede importarse a QML mediante una sentencia import, como los módulos QML.

Por ejemplo, el método fibonacci() del ejemplo anterior podría trasladarse a un archivo externo denominado fib.js, y acceder a él de este modo:

import QtQuick 2.12
import "fib.js" as MathFunctions

Item {
    TapHandler {
        onTapped: console.log(MathFunctions.fibonacci(10))
    }
}

Para obtener más información sobre la carga de archivos JavaScript externos en QML, lea la sección sobre la importación de recursos JavaScript en QML.

Conexión de señales a funciones JavaScript

Los tipos de objeto QML que emiten señales también proporcionan manejadores de señales predeterminados para sus señales, como se describe en la sección anterior. A veces, sin embargo, un cliente desea activar una función definida en un objeto QML cuando otro objeto QML emite una señal. Este tipo de situaciones pueden gestionarse mediante una conexión de señal.

Una señal emitida por un objeto QML puede conectarse a una función JavaScript llamando al método connect() de la señal y pasando la función JavaScript como argumento. Por ejemplo, el código siguiente conecta la señal tapped de TapHandler a la señal jsFunction() de script.js:

import QtQuick
import "script.js" as MyScript

Item {
    id: item
    width: 200; height: 200

    TapHandler {
        id: inputHandler
    }

    Component.onCompleted: {
        inputHandler.tapped.connect(MyScript.jsFunction)
    }
}
// script.js

function jsFunction() {
    console.log("Called JavaScript function!")
}

Se llama a jsFunction() cada vez que se emite la señal TapHandler's tapped.

Consulte Conexión de señales a métodos y señales para obtener más información.

JavaScript en el código de inicio de la aplicación

A veces es necesario ejecutar código imperativo al iniciar la aplicación (o la instancia del componente). Aunque resulta tentador incluir la secuencia de comandos de inicio como código global en un archivo de secuencia de comandos externo, esto puede tener graves limitaciones, ya que es posible que el entorno QML no se haya establecido por completo. Por ejemplo, es posible que no se hayan creado algunos objetos o que no se hayan establecido algunos enlaces de propiedades. Consulte Restricciones del entorno JavaScript para conocer las limitaciones exactas del código de script global.

Un objeto QML emite la señal Component.completed attached cuando se completa su instanciación. El código JavaScript en el manejador Component.onCompleted correspondiente se ejecuta después de instanciar el objeto. Por lo tanto, el mejor lugar para escribir el código de inicio de la aplicación es en el manejador Component.onCompleted del objeto de nivel superior, porque este objeto emite Component.completed cuando el entorno QML está completamente establecido.

Por ejemplo:

import QtQuick 2.0

Rectangle {
    function startupFunction() {
        // ... startup code
    }

    Component.onCompleted: startupFunction();
}

Cualquier objeto de un archivo QML -incluidos los objetos anidados y las instancias de componentes QML anidados- puede utilizar esta propiedad adjunta. Si hay más de un manejador onCompleted() para ejecutar en el inicio, se ejecutan secuencialmente en un orden indefinido.

Del mismo modo, cada Component emite una señal destruction() justo antes de ser destruido.

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.