4 votos

PyQGIS: duplicar un QgsLayoutItemGroup

Quiero añadir mediante programación una cabecera y un pie de página ya que utilizo el atlas con multipáginas para una característica pero no puedo predecir el número de páginas de la tabla en función de la característica. Para añadir la cabecera y el pie de página, quiero copiar un QgsLayoutItemGroup y todos los elementos asociados para posicionarlos en otras páginas. Puedo fácilmente a través de la GUI, copiar y pegar el QgsLayoutItemGroup pero no veo cómo hacerlo con PyQGIS y hacer el cambio automáticamente. Se aceptan sugerencias.

Editar

He cambiado el código de la función original para que sólo se ocupe de los grupos para eliminar las referencias entre objetos y renombrarlos, ya que la respuesta proporcionada mantenía algunas referencias no deseadas entre los grupos. Claramente no es lo suficientemente genérico pero se ajusta a mi caso de uso: un grupo con objetos pero ningún otro grupo dentro de él.

from qgis.PyQt.QtCore import QUuid
from qgis.PyQt.QtXml import QDomDocument
from qgis.core import QgsReadWriteContext

def duplicate_item_group(item, layout, position=None):
    doc = QDomDocument()
    element = doc.createElement('Copied items')
    context = QgsReadWriteContext()

    group_uuid = QUuid.createUuid().toString()
    item.writeXml(element, doc, context)
    if type(item) == QgsLayoutItemGroup:
        print(len(item.items()))
        for subitem in item.items():
            subitem.writeXml(element, doc, context)
    doc.appendChild(element)
    layout_items = doc.elementsByTagName('LayoutItem')
    uuids = []
    for i in range(layout_items.count()):
        item_node = layout_items.at(i + 1)
        if item_node.isElement():
            item_node.toElement().removeAttribute('uuid')
            uuid = QUuid.createUuid().toString()
            uuids.append(uuid)
            item_node.toElement().setAttribute('groupUuid', group_uuid)
            item_node.toElement().setAttribute('templateUuid', uuid)

    group_elements = doc.elementsByTagName('ComposerItemGroupElement')
    for i in range(group_elements.count()):
        item_node = group_elements.at(i)
        if item_node.isElement():
            item_node.toElement().setAttribute('uuid', uuids[i])
    # print(doc.toString()) # To debug the XML content
    if position is None:
        return layout.addItemsFromXml(element, doc, context)
    else:
        return layout.addItemsFromXml(element, doc, context, QPoint(*position))

5voto

Dalroth Puntos 2468

El mecanismo de copiar/pegar para los elementos de diseño se implementa en la clase QgsLayoutView ( copyItems , pasteItems ) .

No estoy seguro de si hay una manera de utilizar estas funciones sin abrir y acceder a la ventana de diseño, pero podemos escribir una función de Python que trabaje directamente con el objeto de diseño:

def duplicate_item(item, layout, position=None):
    doc = QDomDocument('Clipboard')
    element = doc.createElement('Copied items')
    context = QgsReadWriteContext()

    item.writeXml(element, doc, context)
    if type(item) == QgsLayoutItemGroup:
        for subitem in item.items():
            subitem.writeXml(element, doc, context)
    doc.appendChild(element)
    layout_items = doc.elementsByTagName('LayoutItem')
    for i in range(layout_items.count()):
        item_node = layout_items.at(i)
        if item_node.isElement():
            item_node.toElement().removeAttribute('uuid')
            item_node.toElement().removeAttribute('groupUuid')

    if position is None:
        return layout.addItemsFromXml(element, doc, context)
    else:
        return layout.addItemsFromXml(element, doc, context, QPoint(*position))

Por ejemplo, si quieres copiar el primer grupo de la primera distribución a una nueva ubicación, puedes llamar al código de la siguiente manera desde la consola de Python en QGIS:

layout = QgsProject.instance().layoutManager().layouts()[0]
group = [item for item in layout.items() if type(item)==QgsLayoutItemGroup][0]
duplicate_item(group, layout, [50, 80])

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X