Modelos y vistas en Qt Quick
La mayoría de las aplicaciones necesitan dar formato a los datos y mostrarlos. Qt Quick tiene la noción de modelos, vistas y delegados para mostrar los datos. Modularizan la visualización de datos para dar al desarrollador o diseñador control sobre los diferentes aspectos de los datos. Un desarrollador puede cambiar una vista de lista por una vista de cuadrícula con pocos cambios en los datos. Del mismo modo, encapsular una instancia de los datos en un delegado permite al desarrollador dictar cómo presentar o manejar los datos.

- Modelo: contiene los datos y su estructura. Existen varios tipos de QML para crear modelos.
- Vista - un contenedor que muestra los datos. La vista puede mostrar los datos en una lista o en una cuadrícula.
- Delegado - dicta cómo deben aparecer los datos en la vista. El delegado toma cada unidad de datos del modelo y la encapsula. Los datos son accesibles a través del delegado. El delegado también puede volver a escribir datos en modelos editables (por ejemplo, en un TextField's onAccepted Handler).
Para visualizar los datos, vincule la propiedad model de la vista a un modelo y la propiedad delegate a un componente o a otro tipo compatible.
Visualización de datos con vistas
Las vistas son contenedores de colecciones de elementos. Tienen muchas funciones y pueden personalizarse para satisfacer requisitos de estilo o comportamiento.
El conjunto básico de tipos gráficos de Qt Quick incluye una serie de vistas estándar:
- ListView - ordena los elementos en una lista horizontal o vertical
- GridView - ordena los elementos en una cuadrícula dentro del espacio disponible
- PathView - ordena los elementos en un recorrido
- TableView - ordena los datos de QAbstractTableModel en una tabla
- TreeView - ordena los datos de QAbstractItemModel en un árbol
Estos tipos tienen propiedades y comportamientos exclusivos de cada tipo. Visite su documentación respectiva para obtener más información.
Además, Qt Quick Controls contiene algunas vistas y delegados extra que son estilizados de acuerdo al estilo de la aplicación, por ejemplo HorizontalHeaderView y VerticalHeaderView.
Decoración de vistas
Las vistas permiten la personalización visual a través de propiedades de decoración como las propiedades header, footer, y section. Al vincular un objeto, normalmente otro objeto visual, a estas propiedades, las vistas son decorables. Un pie de página puede incluir un tipo Rectangle que muestre los bordes o una cabecera que muestre un logotipo en la parte superior de la lista.
Supongamos que un club concreto quiere decorar su lista de socios con los colores de su marca. La lista de socios está en un model y el delegate mostrará el contenido del modelo.
ListModel { id: nameModel ListElement { name: "Alice" } ListElement { name: "Bob" } ListElement { name: "Jane" } ListElement { name: "Harry" } ListElement { name: "Wendy" } } Component { id: nameDelegate Text { required property string name text: name font.pixelSize: 24 width: ListView.view.width } }
El club puede decorar la lista de socios vinculando objetos visuales a las propiedades header y footer. El objeto visual puede definirse en línea, en otro archivo o en un tipo Component.
ListView { anchors.fill: parent clip: true model: nameModel delegate: nameDelegate header: bannercomponent footer: Rectangle { width: parent.width; height: 30; gradient: clubcolors } highlight: Rectangle { color: "lightgray" } } Component { //instantiated when header is processed id: bannercomponent Rectangle { id: banner width: parent.width; height: 50 gradient: clubcolors border {color: "#9EDDF2"; width: 2} Text { anchors.centerIn: parent text: "Club Members" font.pixelSize: 32 } } } Gradient { id: clubcolors GradientStop { position: 0.0; color: "#8EE2FE"} GradientStop { position: 0.66; color: "#7ED2EE"} }

Manejo del ratón y del tacto
Las vistas gestionan el arrastre y el desplazamiento de su contenido, pero no la interacción táctil con los delegados individuales. Para que los delegados reaccionen a la entrada táctil, por ejemplo, para establecer el currentIndex, el delegado debe proporcionar un MouseArea con la lógica de manejo táctil adecuada.
Tenga en cuenta que si highlightRangeMode se establece en StrictlyEnforceRange, el índice actual se verá afectado al arrastrar o mover la vista, ya que la vista siempre se asegurará de que currentIndex se encuentre dentro del rango de resaltado especificado.
Secciones del ListView
ListView Los contenidos se pueden agrupar en secciones, donde los elementos relacionados de la lista se etiquetan según sus secciones. Además, las secciones pueden decorarse con delegados.
Una lista puede contener una lista que indique los nombres de las personas y el equipo al que pertenecen.
ListModel { id: nameModel ListElement { name: "Alice"; team: "Crypto" } ListElement { name: "Bob"; team: "Crypto" } ListElement { name: "Jane"; team: "QA" } ListElement { name: "Victor"; team: "QA" } ListElement { name: "Wendy"; team: "Graphics" } } Component { id: nameDelegate Text { required property string name text: name; font.pixelSize: 24 anchors.left: parent.left anchors.leftMargin: 2 } }
El tipo ListView tiene la propiedad adjunta section que puede combinar tipos adyacentes y relacionados en una sección. El section.property determina qué propiedad de tipo lista utilizar como secciones. La section.criteria puede dictar cómo se muestran los nombres de las secciones y la section.delegate es similar a la propiedad delegate de las vistas.
ListView { anchors.fill: parent model: nameModel delegate: nameDelegate focus: true highlight: Rectangle { color: "lightblue" width: parent.width } section { property: "team" criteria: ViewSection.FullString delegate: Rectangle { color: "#b0dfb0" width: parent.width height: childrenRect.height + 4 Text { anchors.horizontalCenter: parent.horizontalCenter font.pixelSize: 16 font.bold: true text: section } } } }

Delegados de vista
Las vistas necesitan un delegado para representar visualmente un elemento de una lista. Una vista visualizará cada elemento de la lista según el modelo definido por el delegado. Los elementos de un modelo son accesibles a través de la propiedad index así como de las propiedades del elemento.
Component { id: petdelegate Text { id: label font.pixelSize: 24 text: index === 0 ? type + " (default)" : type required property int index required property string type } }

Posicionamiento de los delegados de vista
El tipo de vista determinará cómo se posicionan los elementos. ListView posicionará los elementos en línea recta, dependiendo de orientation, mientras que GridView puede disponerlos en una cuadrícula de 2 dimensiones. No se recomienda enlazar directamente en x y y, ya que el comportamiento de diseño de la vista siempre tendrá prioridad sobre cualquier enlace posicional.
Acceso a vistas y modelos desde delegados
La vista de lista a la que está vinculado el delegado es accesible desde el delegado a través de la propiedad ListView.view. Del mismo modo, la propiedad GridView GridView.view está disponible para los delegados. El modelo correspondiente y sus propiedades, por tanto, están disponibles a través de ListView.view.model. Además, cualquier señal o método definido en el modelo también es accesible.
Este mecanismo es útil cuando se desea utilizar el mismo delegado para varias vistas, por ejemplo, pero se desea que las decoraciones u otras características sean diferentes para cada vista, y que estos ajustes diferentes sean propiedades de cada una de las vistas. Del mismo modo, puede ser interesante acceder o mostrar algunas propiedades del modelo.
En el siguiente ejemplo, el delegado muestra la propiedad idioma del modelo, y el color de uno de los campos depende de la propiedad color_fruta de la vista.
Rectangle { width: 200; height: 200 ListModel { id: fruitModel property string language: "en" ListElement { name: "Apple" cost: 2.45 } ListElement { name: "Orange" cost: 3.25 } ListElement { name: "Banana" cost: 1.95 } } Component { id: fruitDelegate Row { id: fruit required property string name required property real cost Text { text: " Fruit: " + fruit.name color: fruit.ListView.view.fruit_color } Text { text: " Cost: $" + fruit.cost } Text { text: " Language: " + fruit.ListView.view.model.language } } } ListView { property color fruit_color: "green" model: fruitModel delegate: fruitDelegate anchors.fill: parent } }
Modelos
Los datos se proporcionan al delegado a través de roles de datos con nombre a los que el delegado puede vincularse. Aquí hay un ListModel con dos roles, tipo y edad, y un ListView con un delegado que se une a estos roles para mostrar sus valores:
import QtQuick Item { width: 200 height: 250 ListModel { id: myModel ListElement { type: "Dog"; age: 8; noise: "meow" } ListElement { type: "Cat"; age: 5; noise: "woof" } } component MyDelegate : Text { required property string type required property int age text: type + ", " + age // WRONG: Component.onCompleted: () => console.log(noise) // The above line would cause a ReferenceError // as there is no required property noise, // and the presence of the required properties prevents // noise from being injected into the scope } ListView { anchors.fill: parent model: myModel delegate: MyDelegate {} } }
En la mayoría de los casos deberías usar propiedades requeridas para pasar datos del modelo a tus delegados. Si un delegado contiene propiedades requeridas, el motor QML comprobará si el nombre de una propiedad requerida coincide con el de un rol del modelo. Si es así, esa propiedad se vinculará al valor correspondiente del modelo.
En raras ocasiones, es posible que desee transferir las propiedades del modelo a través del contexto QML en lugar de como propiedades obligatorias. Si no hay propiedades requeridas en su delegado, los roles nombrados se proporcionan como propiedades de contexto:
import QtQuick Item { width: 200; height: 250 ListModel { id: myModel ListElement { type: "Dog"; age: 8 } ListElement { type: "Cat"; age: 5 } } Component { id: myDelegate Text { text: type + ", " + age } } ListView { anchors.fill: parent model: myModel delegate: myDelegate } }
Las propiedades de contexto son invisibles para las herramientas e impiden que el compilador deQt Quick optimice el código. Las propiedades de contexto son invisibles para las herramientas e impiden que el compilador optimice el código. No hay forma de rellenar explícitamente el contexto QML desde QML. Si tu componente espera que los datos se pasen a través del contexto QML, sólo puedes utilizarlo en lugares en los que el contexto adecuado esté disponible a través de medios nativos. Esto puede ser su propio código C++ o las implementaciones específicas de los elementos circundantes. Por el contrario, las propiedades requeridas pueden establecerse de varias formas desde QML o a través de medios nativos. Por lo tanto, pasar datos a través del contexto QML reduce la reutilización de sus componentes.
Si hay un conflicto de nombres entre las propiedades del modelo y las del delegado, se puede acceder a las funciones con el nombre cualificado del modelo. Por ejemplo, si un tipo Text tuviera propiedades (no obligatorias) de tipo o edad, el texto del ejemplo anterior mostraría esos valores de propiedad en lugar de los valores de tipo y edad del elemento del modelo. En este caso, se podría hacer referencia a las propiedades como model.type y model.age para garantizar que el delegado muestra los valores de propiedad del elemento del modelo. Para que esto funcione, necesitas requerir una propiedad model en tu delegado (a menos que estés usando propiedades de contexto).
El delegado también dispone de una función de índice especial que contiene el índice del elemento del modelo. Ten en cuenta que este índice se establece en -1 si el elemento se elimina del modelo. Si se vincula a la función de índice, asegúrese de que la lógica tiene en cuenta la posibilidad de que el índice sea -1, es decir, que el elemento ya no sea válido. (Normalmente el elemento se destruirá en breve, pero es posible retrasar la destrucción delegada en algunas vistas a través de una propiedad adjunta delayRemove ).
Recuerda que puedes utilizar enteros o matrices como modelo:
Repeater { model: ["one", "two", "three"] Text { required property string modelData text: modelData } }
Tales modelos proporcionan una pieza singular y anónima de datos a cada instancia del delegado. Acceder a esta pieza de datos es la razón principal para utilizar modelData, pero otros modelos también proporcionan modelData.
El objeto proporcionado a través del rol model tiene una propiedad con un nombre vacío. Esta propiedad anónima contiene el modelData. Además, el objeto proporcionado a través del rol model tiene otra propiedad llamada modelData. Esta propiedad está obsoleta y también contiene el modelData.
Además del rol model, se proporciona un rol modelData. El rol modelData contiene los mismos datos que la propiedad modelData y la propiedad anonymous del objeto proporcionado a través del rol model.
Las diferencias entre el rol de modelo y los distintos medios para acceder a modelData son las siguientes:
- Los modelos que no tienen roles con nombre (como los enteros o un array de cadenas) tienen sus datos proporcionados a través del rol modelData. En este caso, el rol modelData no contiene necesariamente un objeto. En el caso de un modelo entero, contendría un número entero (el índice del elemento actual del modelo). En el caso de una matriz de cadenas, contendría una cadena. El rol del modelo todavía contiene un objeto, pero sin ninguna propiedad para roles con nombre. Sin embargo, el modelo todavía contiene sus propiedades habituales modelData y anonymous.
- Si el modelo sólo tiene un rol con nombre, el rol modelData contiene los mismos datos que el rol con nombre. No es necesariamente un objeto y no contiene el rol con nombre como una propiedad con nombre como lo haría normalmente. El rol modelo aún contiene un objeto con el rol nombrado como propiedad, y las propiedades modelData y anonymous en este caso.
- Para modelos con múltiples roles, el rol modelData sólo se proporciona como una propiedad requerida, no como una propiedad de contexto. Esto se debe a la compatibilidad con versiones anteriores de Qt.
La propiedad anónima en el modelo te permite escribir limpiamente delegados que reciben tanto los datos de su modelo como el nombre del rol al que deben reaccionar como propiedades desde el exterior. Puedes proporcionar un modelo sin o con un solo rol con nombre, y una cadena vacía como rol. Entonces, un enlace que simplemente acceda a model[role] hará lo que esperas. No tienes que añadir código especial para este caso.
Nota: Los roles model, index y modelData no son accesibles si el delegado contiene propiedades requeridas, a menos que también tenga propiedades requeridas con nombres coincidentes.
QML proporciona varios tipos de modelos de datos entre el conjunto incorporado de tipos QML. Además, los modelos pueden crearse con Qt C++ y luego ponerse a disposición de QQmlEngine para que los utilicen los componentes QML. Para obtener información sobre la creación de estos modelos, visite los artículos Uso de modelos C++ con Qt Quick Views y Creación de tipos QML.
El posicionamiento de los elementos de un modelo puede lograrse utilizando un Repeater.
Modelo de lista
ListModel es una jerarquía simple de tipos especificados en QML. Las funciones disponibles se especifican mediante las propiedades ListElement.
ListModel { id: fruitModel ListElement { name: "Apple" cost: 2.45 } ListElement { name: "Orange" cost: 3.25 } ListElement { name: "Banana" cost: 1.95 } }
El modelo anterior tiene dos roles, nombre y coste. Estos pueden ser vinculados por un delegado ListView, por ejemplo:
ListView { anchors.fill: parent model: fruitModel delegate: Row { id: delegate required property string name required property real cost Text { text: "Fruit: " + delegate.name } Text { text: "Cost: $" + delegate.cost } } }
ListModel proporciona métodos para manipular el ListModel directamente a través de JavaScript. En este caso, el primer elemento insertado determina los roles disponibles para cualquier vista que utilice el modelo. Por ejemplo, si se crea un ListModel vacío y se rellena mediante JavaScript, los roles proporcionados por la primera inserción son los únicos roles que se mostrarán en la vista:
ListModel { id: fruitModel } ... MouseArea { anchors.fill: parent onClicked: fruitModel.append({"cost": 5.95, "name":"Pizza"}) }
Cuando se haga clic en MouseArea, fruitModel tendrá dos roles, coste y nombre. Incluso si se añaden roles posteriores, sólo los dos primeros serán manejados por las vistas que utilicen el modelo. Para restablecer los roles disponibles en el modelo, llame a ListModel::clear().
Modelo XML
XmlListModel permite construir un modelo a partir de una fuente de datos XML. Los roles se especifican a través del tipo XmlListModelRole. Es necesario importar el tipo.
import QtQml.XmlListModel
El siguiente modelo tiene tres roles, title, link y pubDate:
XmlListModel { id: feedModel source: "http://rss.news.yahoo.com/rss/oceania" query: "/rss/channel/item" XmlListModelRole { name: "title"; elementName: "title" } XmlListModelRole { name: "link"; elementName: "link" } XmlListModelRole { name: "pubDate"; elementName: "pubDate" } }
La propiedad query especifica que el XmlListModel genera un elemento del modelo para cada <item> en el documento XML.
La demostración de noticias RSS muestra cómo puede utilizarse XmlListModel para mostrar un canal RSS.
Modelo de objeto
ObjectModel contiene los elementos visuales que se utilizarán en una vista. Cuando se utiliza un ObjectModel en una vista, ésta no necesita un delegado porque el ObjectModel ya contiene el delegado visual (elementos).
El ejemplo siguiente coloca tres rectángulos de colores en un ListView.
import QtQuick 2.0 import QtQml.Models 2.1 Rectangle { ObjectModel { id: itemModel Rectangle { height: 30; width: 80; color: "red" } Rectangle { height: 30; width: 80; color: "green" } Rectangle { height: 30; width: 80; color: "blue" } } ListView { anchors.fill: parent model: itemModel } }
Enteros como modelos
Un número entero puede utilizarse como un modelo que contiene un cierto número de tipos. En este caso, el modelo no tiene ninguna función de datos.
El siguiente ejemplo crea un ListView con cinco elementos:
Item { width: 200; height: 250 Component { id: itemDelegate Text { required property int index text: "I am item number: " + index } } ListView { anchors.fill: parent model: 5 delegate: itemDelegate } }
Nota: El límite del número de elementos en un modelo entero es 100.000.000.
Instancias de objetos como modelos
Una instancia de objeto puede utilizarse para especificar un modelo con un único tipo de objeto. Las propiedades del objeto se proporcionan como roles.
El siguiente ejemplo crea una lista con un elemento, mostrando el color del texto miTexto. Nótese el uso de la propiedad model.color completamente cualificada para evitar chocar con la propiedad color del tipo Text en el delegado.
Rectangle { width: 200; height: 250 Text { id: myText text: "Hello" color: "#dd44ee" } Component { id: myDelegate Text { required property var model text: model.color } } ListView { anchors.fill: parent anchors.topMargin: 30 model: myText delegate: myDelegate } }
Modelos de datos C
Los modelos pueden definirse en C++ y ponerse a disposición de QML. Este mecanismo es útil para exponer modelos de datos C++ existentes o conjuntos de datos complejos a QML.
Para obtener más información, visite el artículo Uso de modelos C++ con vistas Qt Quick .
Modelos de matrices
Puede utilizar matrices JavaScript y varios tipos de listas QML como modelos. Los elementos de la lista estarán disponibles como model y modelData según las reglas descritas anteriormente: Los datos singulares, como números enteros o cadenas, están disponibles como modelData singular. Los datos estructurados, como objetos JavaScript o QObjects, están disponibles como modelData y modelData estructurados.
Los roles individuales del modelo también están disponibles si se solicitan como propiedades requeridas. Dado que no podemos saber de antemano qué objetos aparecerán en un array, cualquier propiedad requerida en un delegado se rellenará, posiblemente con una coerción de undefined al tipo requerido. Sin embargo, las funciones individuales del modelo no están disponibles a través del contexto QML. Serían la sombra de todas las demás propiedades del contexto.
Repetidores

Los repetidores crean elementos a partir de una plantilla para su uso con posicionadores, utilizando datos de un modelo. Combinar repetidores y posicionadores es una forma sencilla de disponer muchos elementos. Un elemento Repeater se coloca dentro de un posicionador, y genera elementos que el posicionador que lo encierra ordena.
Cada repetidor crea un número de elementos combinando cada elemento de datos de un modelo, especificado mediante la propiedad model, con el elemento del modelo, definido como elemento hijo dentro del repetidor. El número total de elementos viene determinado por la cantidad de datos del modelo.
El siguiente ejemplo muestra un repetidor utilizado con un elemento Grid para organizar un conjunto de elementos Rectangle. El elemento Repetidor crea una serie de 24 rectángulos para que el elemento Cuadrícula los coloque en una disposición de 5 por 5.
import QtQuick Rectangle { width: 400 height: 400 color: "black" Grid { x: 5 y: 5 rows: 5 columns: 5 spacing: 10 Repeater { model: 24 Rectangle { id: delegate required property int index width: 70 height: 70 color: "lightgreen" Text { text: delegate.index font.pointSize: 30 anchors.centerIn: parent } } } } }
El número de elementos creados por un Repetidor se mantiene mediante su propiedad count. No es posible establecer esta propiedad para determinar el número de elementos a crear. En su lugar, como en el ejemplo anterior, utilizamos un número entero como modelo.
Para más detalles, consulte el documento Modelos de datos QML.
Si el modelo es una lista de cadenas, el delegado también está expuesto a la propiedad habitual de sólo lectura modelData que contiene la cadena. Por ejemplo:
|
También es posible utilizar un delegado como modelo para los elementos creados por un Repetidor. Esto se especifica utilizando la propiedad delegate.
Modificación de los datos del modelo
Todas las vistas relevantes tienen una propiedad llamada delegateModelAccess que gobierna si y cómo puedes cambiar los datos del modelo desde el delegado. Para la mayoría de los casos de uso, debe establecerla en DelegateModel.ReadWrite. De este modo, el delegado podrá modificar los datos del modelo de la forma más flexible. Alternativamente, puedes establecerlo en DelegateModel.ReadOnly si no quieres que el delegado cambie ningún dato del modelo.
La siguiente tabla describe en detalle todos los valores que puede tener la propiedad.
| DelegateModel.Qt5ReadWrite | El delegado puede asignar valores a cualquier propiedad de contexto proporcionada por la vista para cambiar el elemento del modelo correspondiente. Además, también puede asignar valores a propiedades del objeto model proporcionadas como propiedad de contexto o propiedad requerida para el mismo efecto. Sin embargo, el delegado no puede cambiar los datos del modelo asignando valores a las propiedades requeridas rellenadas por la vista. Si asignas un valor a una propiedad obligatoria de un delegado, se rompe el enlace que actualiza la propiedad obligatoria a partir de los datos del modelo. Esto hace que la propiedad requerida mantenga el valor que le has asignado incluso si el modelo cambia más tarde. DelegateModel.Qt5ReadWrite es el valor por defecto de delegateModelAccess. |
| DelegateModel.ReadOnly | El delegado no puede asignar valores a propiedades de contexto proporcionadas por la vista, ni puede asignar valores a propiedades del objeto model. Asignar un valor a una propiedad requerida rellenada por la vista no rompe el enlace interno, ni cambiará ningún dato del modelo. La propiedad requerida mantendrá el valor asignado hasta que el elemento del modelo vuelva a cambiar. |
| DelegateModelLectura y escritura | El delegado puede asignar valores a cualquier propiedad de contexto proporcionada por la vista para cambiar el elemento del modelo correspondiente. Además, también puede asignar valores a propiedades del objeto model proporcionadas como propiedad de contexto o propiedad requerida con el mismo efecto. El delegado también puede cambiar los datos del modelo asignando valores a las propiedades requeridas rellenadas por la vista. Al asignar un valor a una propiedad obligatoria, el valor se propagará al elemento del modelo correspondiente y no se romperán los enlaces internos. |
Algunos modelos son objetos con identidades independientes a los que la vista hace referencia. El objeto original es la única fuente de verdad para crear delegados. No se copia. Tales modelos se actualizarán visiblemente al escribir a través de delegados.
Otros modelos no tienen una identidad independiente y se copian al asignarlos a la vista. Para estos modelos, sólo se actualizan los elementos internos de la vista cuando se escribe a través del delegado. El modelo original permanece inalterado.
En general, los tipos de objeto QML tienen identidades independientes, mientras que los tipos de valor QML no. Por lo tanto, ListModel, cualquier cosa derivada de QAbstractItemModel, así como una única instancia de un tipo de objeto o una lista de instancias de tipos de objeto se actualizarán cuando se pasen como modelo y se escriban a través del delegado. Sin embargo, las matrices de JavaScript, las listas de tipos de valor o los números simples no reciben actualizaciones cuando se cambian los datos del modelo a través del delegado.
Además, al implementar tu propio modelo C++, necesitas implementar setData para recibir cualquier actualización pasada desde los delegados.
Supongamos que un modelo C++ basado en QAbstractItemModel que implemente el método setData se registra como un tipo QML denominado EditableModel. Los datos podrían escribirse en el modelo de la siguiente manera:
ListView { anchors.fill: parent model: EditableModel {} // Make sure that changes to the required property are propagated delegateModelAccess: DelegateModel.ReadWrite delegate: TextEdit { required property string edit width: ListView.view.width height: 30 text: edit Keys.onReturnPressed: edit = text } }
También se pueden cambiar los datos del modelo manipulando el objeto model de esta manera:
ListView { anchors.fill: parent model: EditableModel {} delegate: TextEdit { required property QtObject model width: ListView.view.width height: 30 text: model.edit Keys.onReturnPressed: model.edit = text } }
Nota: El rol edit es igual a Qt::EditRole. Ver roleNames() para los nombres de roles incorporados. Sin embargo, los modelos de la vida real suelen registrar roles personalizados.
Para obtener más información, visite el artículo Uso de modelos C++ con vistas Qt Quick .
Uso de transiciones
Las transiciones pueden utilizarse para animar elementos que se añaden, mueven o eliminan de un posicionador.
Las transiciones para añadir elementos se aplican a los elementos que se crean como parte de un posicionador, así como a los que se reasignan para convertirse en hijos de un posicionador.
Las transiciones para eliminar elementos se aplican a los elementos que se eliminan dentro de un posicionador, así como a los que se eliminan de un posicionador y se les asignan nuevos padres en un documento.
Nota: Cambiar la opacidad de los elementos a cero no hará que desaparezcan del posicionador. Se pueden eliminar y volver a añadir cambiando la propiedad visible.
© 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.
