Ámbito y resolución de nombres
Los enlaces de propiedades QML, las funciones en línea y los archivos JavaScript importados se ejecutan en un ámbito JavaScript. El ámbito controla a qué variables puede acceder una expresión y qué variable tiene prioridad cuando dos o más nombres entran en conflicto.
Dado que el mecanismo de ámbito integrado de JavaScript es muy sencillo, QML lo mejora para que se adapte de forma más natural a las extensiones del lenguaje QML.
Ámbito de JavaScript
Las extensiones de ámbito de QML no interfieren con el ámbito natural de JavaScript. Los programadores de JavaScript pueden reutilizar sus conocimientos existentes al programar funciones, enlaces de propiedades o archivos JavaScript importados en QML.
En el siguiente ejemplo, el método addConstant() añadirá 13 al parámetro pasado tal y como esperaría el programador, independientemente del valor de las propiedades a y b del objeto QML.
QtObject { property int a: 3 property int b: 9 function addConstant(b) { var a = 13; return b + a; } }
El hecho de que QML respete las reglas de alcance normales de JavaScript se aplica incluso en los enlaces. Esta abominación totalmente maligna asignará 12 a la propiedad a del objeto QML.
Cada expresión, función o archivo JavaScript en QML tiene su propio objeto variable único. Las variables locales declaradas en uno nunca entrarán en conflicto con las variables locales declaradas en otro.
Nombres de tipo y archivos JavaScript importados
Los documentos QML incluyen sentencias import que definen los nombres de tipo y los archivos JavaScript visibles para el documento. Además de su uso en la propia declaración QML, los nombres de tipo son utilizados por el código JavaScript cuando accede a propiedades adjuntas y valores de enumeración.
El efecto de una importación se aplica a todos los enlaces de propiedades y funciones JavaScript del documento QML, incluso a los que se encuentran en componentes anidados en línea. El siguiente ejemplo muestra un archivo QML sencillo que accede a algunos valores de enumeración y llama a una función JavaScript importada.
import QtQuick 2.0 import "code.js" as Code ListView { snapMode: ListView.SnapToItem delegate: Component { Text { elide: Text.ElideMiddle text: "A really, really long string that will require eliding." color: Code.defaultColor() } } }
Objeto de ámbito vinculante
Un objeto que tiene una propiedad vinculante se conoce como objeto de ámbito de la vinculación. En el siguiente ejemplo, el objeto Item es el objeto de ámbito del enlace.
Item { anchors.left: parent.left }
Los enlaces tienen acceso a las propiedades del objeto de ámbito sin restricciones. En el ejemplo anterior, el enlace accede directamente a la propiedad parent de Item, sin necesidad de ningún tipo de prefijo de objeto. QML introduce un enfoque más estructurado y orientado a objetos de JavaScript y, en consecuencia, no requiere el uso de la propiedad this de JavaScript.
Hay que tener cuidado al acceder a propiedades adjuntas desde bindings debido a su interacción con el objeto scope. Conceptualmente, las propiedades adjuntas existen en todos los objetos, aunque sólo tengan efecto en un subconjunto de ellos. En consecuencia, las lecturas de propiedades adjuntas no cualificadas siempre se resolverán a una propiedad adjunta en el objeto de ámbito, que no siempre es lo que el programador pretendía.
Por ejemplo, el tipo PathView adjunta propiedades de valor interpolado a sus delegados dependiendo de su posición en la ruta. Dado que PathView sólo adjunta de forma significativa estas propiedades al objeto raíz del delegado, cualquier subobjeto que acceda a ellas debe calificar explícitamente al objeto raíz, como se muestra a continuación.
Si el objeto Image omitiera el prefijo root, accedería inadvertidamente a la propiedad PathView.scale adjunta a sí mismo.
Ámbito de los componentes
Cada componente QML de un documento QML define un ámbito lógico. Cada documento tiene al menos un componente raíz, pero también puede tener otros subcomponentes en línea. El ámbito del componente es la unión de los identificadores de objeto dentro del componente y las propiedades del objeto raíz del componente.
Item {
property string title
Text {
id: titletype
text: "<b>" + title + "</b>"
font.pixelSize: 22
anchors.top: parent.top
}
Text {
text: titletype.text
font.pixelSize: 18
anchors.bottom: parent.bottom
}
}El ejemplo anterior muestra un componente QML sencillo que muestra una cadena de título de texto enriquecido en la parte superior y una copia más pequeña del mismo texto en la parte inferior. El primer tipo Text accede directamente a la propiedad title del componente cuando forma el texto a mostrar. El hecho de que se pueda acceder directamente a las propiedades del tipo raíz hace que sea trivial distribuir los datos por todo el componente.
El segundo tipo Text utiliza un id para acceder directamente al texto del primero. Los ID son especificados explícitamente por el programador de QML, por lo que siempre tienen prioridad sobre otros nombres de propiedades (excepto los del ámbito JavaScript). Por ejemplo, en el improbable caso de que el objeto scope del binding tuviera una propiedad titletype en el ejemplo anterior, el id titletype seguiría teniendo preferencia.
Jerarquía de instancias de componentes
En QML, las instancias de componentes conectan sus ámbitos de componentes para formar una jerarquía de ámbitos. Las instancias de componentes pueden acceder directamente a los ámbitos de componentes de sus antepasados.
La forma más sencilla de demostrarlo es con subcomponentes en línea cuyos ámbitos de componente se definen implícitamente como hijos del componente externo.
Item { property color defaultColor: "blue" ListView { delegate: Component { Rectangle { color: defaultColor } } } }
La jerarquía de instancias de componentes permite a las instancias del componente delegado acceder a la propiedad defaultColor del tipo Item. Por supuesto, si el componente delegado hubiera tenido una propiedad llamada defaultColor, ésta habría tenido prioridad.
La jerarquía del ámbito de instancia del componente también se extiende a los componentes fuera de línea. En el siguiente ejemplo, el componente TitlePage.qml crea dos instancias TitleText. Aunque el tipo TitleText se encuentra en un archivo independiente, sigue teniendo acceso a la propiedad title cuando se utiliza desde TitlePage. QML es un lenguaje de ámbito dinámico: dependiendo de dónde se utilice, la propiedad title puede resolverse de forma diferente.
// TitlePage.qml
import QtQuick 2.0
Item {
property string title
TitleText {
size: 22
anchors.top: parent.top
}
TitleText {
size: 18
anchors.bottom: parent.bottom
}
}
// TitleText.qml
import QtQuick 2.0
Text {
property int size
text: "<b>" + title + "</b>"
font.pixelSize: size
}El ámbito dinámico es muy potente, pero debe utilizarse con precaución para evitar que el comportamiento del código QML sea difícil de predecir. En general, sólo debe utilizarse en los casos en que los dos componentes ya estén estrechamente acoplados de otra forma. Al construir componentes reutilizables, es preferible utilizar interfaces de propiedades, como ésta:
// TitlePage.qml
import QtQuick 2.0
Item {
id: root
property string title
TitleText {
title: root.title
size: 22
anchors.top: parent.top
}
TitleText {
title: root.title
size: 18
anchors.bottom: parent.bottom
}
}
// TitleText.qml
import QtQuick 2.0
Text {
property string title
property int size
text: "<b>" + title + "</b>"
font.pixelSize: size
}No haga referencia al objeto raíz id desde otros componentes QML
Evite acceder a id de un objeto raíz desde fuera del archivo QML en el que está definido. Los valores de id sólo son válidos dentro del mismo documento, y confiar en ellos desde otros componentes rompe la encapsulación y los límites de los componentes.
// Main.qml import QtQuick Item { id: root CustomItem { } } // CustomItem.qml import QtQuick Rectangle { width: root.width height: root.height / 2 color: "red" }
En el ejemplo anterior, root no está declarado en CustomItem.qml. El código sigue funcionando porque CustomItem se instancia en un contexto en el que existe root, lo que está permitido por las reglas de ámbito dinámico de QML. Sin embargo, esto crea una dependencia implícita del ámbito externo, lo que hace que el componente sea poco fiable y más difícil de reutilizar cuando se carga dinámicamente o se utiliza en un contexto diferente. Este patrón también puede dar lugar a errores sutiles. Por ejemplo, si otro objeto de la cadena de ámbito utiliza el mismo id, puede hacer sombra al esperado, dando lugar a un comportamiento inesperado.
Para que los componentes sean fiables y reutilizables, accede al estado externo sólo a través de propiedades explícitas, alias de propiedades o señales. Evite depender de valores de ámbito externo id.
El siguiente ejemplo sustituye el ámbito dinámico por una API de componentes explícita.
// Main.qml import QtQuick import QtQuick.Window Window { id: root width: 400 height: 300 visible: true CustomItem { width: root.width height: root.height boxColor: "blue" } } // CustomItem.qml import QtQuick Item { id: container property alias boxColor: rect.color Rectangle { id: rect width: container.width height: container.height / 2 color: "red" } }
Aplique la misma regla a todos los objetos internos declarados con id dentro de un componente.
// MyItem.qml import QtQuick Item { Item { id: internalCounter property int count: 5 } } // main.qml import QtQuick MyItem { Component.onCompleted: { console.log(internalCounter.count); } }
En el ejemplo anterior, el acceso a id internalCounter desde otro archivo QML provoca un ReferenceError porque id es un documento local y no se puede acceder a él fuera del archivo QML en el que está declarado.
Si un objeto interno necesita exponer su estado o comportamiento, exponlo explícitamente a través de propiedades, alias de propiedades o señales.
El siguiente ejemplo expone el estado interno a través de una API de componente explícita en lugar de confiar en el acceso directo a un documento local id.
// MyItem.qml import QtQuick Item { Item { id: internalCounter property int count: 5 } property alias internalCount: internalCounter.count } // main.qml import QtQuick MyItem { Component.onCompleted: { console.log(internalCount); } }
Esto ayuda a mantener claros los límites de los componentes y mejora la escalabilidad y la comprobabilidad.
Propiedades sobrescritas
QML permite que los nombres de propiedades definidos en una declaración de objeto sean sustituidos por propiedades declaradas en otra declaración de objeto que extienda la primera. Por ejemplo:
// Displayable.qml
import QtQuick 2.0
Item {
property string title
property string detail
Text {
text: "<b>" + title + "</b><br>" + detail
}
function getTitle() { return title }
function setTitle(newTitle) { title = newTitle }
}
// Person.qml
import QtQuick 2.0
Displayable {
property string title
property string firstName
property string lastName
function fullName() { return title + " " + firstName + " " + lastName }
}Aquí, el nombre title se da tanto al encabezado del texto de salida para Displayable, como al título honorífico del objeto Person.
Una propiedad anulada se resuelve según el ámbito en el que se hace referencia a ella. Dentro del ámbito del componente Persona, o desde un ámbito externo que haga referencia a una instancia del componente Persona, title resuelve a la propiedad declarada dentro de Person.qml. La función fullName hará referencia a la propiedad title declarada dentro de Person.
Sin embargo, dentro del componente Displayable, title hace referencia a la propiedad declarada en Displayable.qml. Las funciones getTitle() y setTitle(), y el enlace para la propiedad text del objeto Text harán referencia a la propiedad title declarada en el componente Displayable.
A pesar de compartir el mismo nombre, las dos propiedades son completamente independientes. Un controlador de señal onChanged para una de las propiedades no se activará por un cambio en la otra propiedad con el mismo nombre. Un alias de cualquiera de las propiedades hará referencia a una u otra, pero no a ambas.
Objeto global JavaScript
QML prohíbe los nombres de tipo, id y propiedad que entren en conflicto con las propiedades del objeto global para evitar cualquier confusión. Los programadores pueden estar seguros de que Math.min(10, 9) funcionará siempre como se espera.
Consulte Entorno de host JavaScript para obtener más información.
© 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.