versiones guia español actualizar qml qt-quick

guia - ¿Cómo definir una “plantilla” con marcadores de posición secundarios en QML?



qgis español (5)

En definitiva (para mostrar la idea):

import QtQuick 1.1 Item { width: 200 height: 100 //<-- the client can set the placeholder content here property Item contents: Rectangle { anchors.fill: parent anchors.margins: 25 color: "red" } Rectangle { id: container anchors.fill: parent radius: 10 color: "gray" //<-- where the placeholder should be inserted } Component.onCompleted: { contents.parent = container } }

Versión algo más larga (reasignación de contenidos de soporte):

import QtQuick 1.1 Item { width: 200 height: 100 //<-- the client can set the placeholder content here property Item contents: Rectangle { //anchors can be "presupplied", or set within the insertion code //anchors.fill: parent //anchors.margins: 25 color: "red" } Rectangle { id: container anchors.fill: parent radius: 10 color: "gray" //<-- where the placeholder should be inserted //Item { // id: placeholder //} } //"__" means private by QML convention function __insertContents() { // move the contents into the placeholder... contents.parent = container contents.anchors.fill = container contents.anchors.margins = 25 } onContentsChanged: { if (contents !== null) __insertContents() } Component.onCompleted: { __insertContents() } }

Espero que esto ayude :)

Realmente me gusta QML. Me gusta cómo puedo definir los componentes (comparables a las clases) y sus propiedades, e instanciarlos desde otro lugar (comparable a los objetos).

Puedo definir, digamos, un botón, con cierto aspecto y un texto de etiqueta en él. Esto se podría hacer, por ejemplo, usando esta definición de componente ( Button.qml ):

Item { id: button property string label anchors.fill: parent Rectangle { anchors.fill: parent radius: 10 color: "gray" Text { anchors.centerIn: parent font.pixelSize: 20 text: button.label color: "white" } } }

e instanciados en este archivo principal ( main.qml ):

Rectangle { width: 300 height: 200 Button { anchors.centerIn: parent anchors.margins: 50 label: "Hello button!" } }

Pero veo la siguiente restricción: solo puedo definir una plantilla de botón con algunas propiedades , no con algún marcador de posición . Todos los hijos definidos en la instancia serán hijos directos, al menos por defecto, y quiero cambiar este comportamiento.

Digamos que quiero colocar un elemento (digamos una imagen, pero no quiero decirle a la definición de Button que será una imagen) en el botón. Me imagino algo como esto:

Item { id: button property Item contents <-- the client can set the placeholder content here anchors.fill: parent Rectangle { anchors.fill: parent radius: 10 color: "gray" Item { id: placeholder <-- where the placeholder should be inserted } } Component.onCompleted: { // move the contents into the placeholder... } }

¿Cómo puedo conseguir esto? No sé si usar Component.onCompleted es la forma correcta. Tenga en cuenta que, en mi caso, el contenido nunca cambiará después (al menos en mi diseño actual de la aplicación ...).

Además, quiero que el anclaje funcione dentro del marcador de posición. Por ejemplo, si defino el contenido como un elemento de Texto, centrado en su elemento primario (que primero será la propia plantilla). Luego mi código mueve esta instancia de Texto al marcador de posición y los anclajes primarios deben ser los del elemento marcador de posición, no el elemento de la plantilla.


En realidad, la respuesta correcta de lo que he escuchado es usar un cargador QML para lograr lo que quieres.

[habiendo dicho eso; Aún no lo he intentado pero está en mi lista de intentos a corto plazo y parece bastante sencillo]

Además, busque para otras preguntas sobre el "Cargador QML" ya que hay un número que lo ayudará a comenzar.


Encontré una respuesta mucho mejor a esta pregunta, sugerida en una presentación de Qt Developer Days 2011 "Qt Quick Best Practices and Design Patterns" .

Usan el default property alias ... para asignar alias a los elementos secundarios a cualquier propiedad de cualquier elemento. Si no desea asignar un alias a los hijos, pero asigne un nombre a la propiedad de alias, simplemente elimine el default . (Los hijos literales son por definición de QML el valor de la propiedad predeterminada).

Item { id: button default property alias contents: placeholder.children anchors.fill: parent Rectangle { anchors.fill: parent radius: 10 color: "gray" Item { id: placeholder <-- where the placeholder should be inserted } } }


Necro responde en caso de que alguien más termine aquí como yo.

En Qt5, en algún lugar a lo largo de la línea, la propiedad predeterminada se convirtió en " data " y no en "hijos". Esto hace posible agregar otros tipos de objeto que "Elemento". Por ejemplo, también se pueden agregar conexiones (para responder a mi propia pregunta arriba)

Así que en Qt5 debes hacer:

Item { id: button default property alias contents: placeholder.data anchors.fill: parent Rectangle { anchors.fill: parent radius: 10 color: "gray" Item { id: placeholder <-- where the placeholder should be inserted } } }

Tenga en cuenta: placeholder.data lugar de placeholder.children También tenga en cuenta que no tiene que usar el contents nombre de alias; esto puede ser lo que quiera. Un ejemplo:

Item { id: button default property alias foo: placeholder.data ... }


Puede mover los elementos (si desea admitir varios elementos dentro del marcador de posición) utilizando este código:

property list<Item> contents Component.onCompleted: { var contentItems = []; for(var i = 0; i < contents.length; ++i) contentItems.push(contents[i]); placeholder.children = contentItems; }

Tenga en cuenta que no tiene que proporcionar una lista de elementos para la propiedad de contenido, ya que el motor QML también aceptará valores únicos para las propiedades de lista.