Soluções‎ > ‎

QmlPrinter

QML é uma linguagem de descrição de tela criada recentemente pela Nokia para o Qt Quick. Reduz muito o tempo de desenvolvimento e permite criar visuais bastante elaborados, modernos e com animações fantásticas.
Porém, criar aplicativos em QML que necessitem a impressão de relatórios e telas pode ser uma tarefa desgastante e consumir vários dias de desenvolvimento na tentativa de reproduzir o conteúdo QML em uma saída de impressão.

O QmlPrinter é composto por uma engine de impressão que faz um parseamento dinâmico dos objetos QML criados em memória e remonta-os em uma saída de impressão, fazendo controle de paginação e permitido adicionar cabeçalhos, rodapés e notas a impressão.

Como exemplo, abaixo está um código QML simples de uma tela de vendas genérica.
Observe que para imprimir a tela basta chamar a função qmlPrinter.print() e passar o objeto a ser impresso, indicar se a saída é para impressão ou geração de pdf e o nome do relatório.

 import QtQuick 1.0
Item {
    id: root
    width: 500; height: 400
    ListView {
        id: listview1
        objectName: "_StartHeader:1_" // A partir deste ponto sempre que ocorrer uma quebra de pagina o
                                      // objeto declarado como Header:1 sera o cabecalho da nova pagina.
        anchors.fill: parent
        model: myModel
        cacheBuffer: myModel.count * 20
        header: Rectangle {
            objectName: "_Header:1_" //Declaramos que este objeto sera o cabecalho das paginas
            height: 20
            width: parent.width
            color: "blue"
            Text {
                text: "Produto"
                anchors {
                    left: parent.left
                    leftMargin: 10
                    verticalCenter: parent.verticalCenter
                }
            }
            Text {
                text: "Preço"
                width: 80
                anchors {
                    right: btnImprimir.left
                    rightMargin: 20
                    verticalCenter: parent.verticalCenter
                }
            }
            Button {
                id: btnImprimir
                objectName: "_NoPrint_" // Nao queremos que botoes sejam impressos.
                                        // poderiamos ter adicionado _NoPrint_ dentro do componente
                                        // Button para que nenhum botao seja impresso.
                text: "Imprimir"
                color: "darkgray"
                anchors {
                    right: btnPdf.left
                    rightMargin: 20
                    verticalCenter: parent.verticalCenter
                }
                onButtonClick: {
                    qmlPrinter.print(false, root, "Nome do Relatório");
                }
            }
            Button {
                id: btnPdf
                objectName: "_NoPrint_"
                text: "PDF"
                color: "darkgray"
                anchors {
                    right: parent.right
                    rightMargin: 20
                    verticalCenter: parent.verticalCenter
                }
                onButtonClick: {
                    qmlPrinter.print(true, root, "Nome do Relatório");
                }
            }
        }
        delegate: Rectangle {
            width: parent.width
            height: 20
            color: "grey"
            Text {
                id: txtProduto
                anchors {
                    left: parent.left
                    leftMargin: 10
                    verticalCenter: parent.verticalCenter
                }
                text: produto
            }
            Text {
                id: txtPreco
                width: 80
                anchors {
                    right: btnDetalhes.left
                    rightMargin: 20
                    verticalCenter: parent.verticalCenter
                }
                text: preco
            }
            Button {
                id: btnDetalhes
                objectName: "_NoPrint_"
                text: "Detalhes"
                anchors {
                    right: btnComprar.left
                    rightMargin: 20
                    verticalCenter: parent.verticalCenter
                }
            }
            Button {
                id: btnComprar
                objectName: "_NoPrint_"
                text: "Comprar"
                anchors {
                    right: parent.right
                    rightMargin: 20
                    verticalCenter: parent.verticalCenter
                }
            }
        }
    }
}


Esta é a tela gerada pelo código acima. Queremos que ao imprimi-la não apareçam os botões, e por isso adicionamos as diretivas _NoPrint_ na propriedade objectName dos objetos Button. Também foi definido o objeto que será usado como cabeçalho das páginas quando ocorrer uma quebra, através das diretivas _Header:1_ e _StartHeader:1_. Note que é possível ter vários cabeçalhos definidos.


Ao clicarmos em imprimir esta será a saída.

Existem diversas diretivas que podem ser usadas para modificar a impressão dos objetos, como também podemos alterá-los no código c++ que herda a engine de impressão.
Podemos adicionar objetos visíveis somente para impressão ou modificar os objetos atuais. Neste exemplo, além de remover os botões, seria possível remover o fundo cinza para o usuário não gastar muita tinta ao imprimir.
O primeiro cabeçalho, os rodapés e a nota no final da impressão são adicionados de código c++, reimplementando as funções virtuais da engine.
A engine também cuida de todo o controle de dimensionamento e alinhamento dos objetos.

Esta solução está disponível sob licença GPL em: https://github.com/rafaelfassi/qmlprinter
Caso queira usar esta solução para fins comerciais, entre em contato.
Também possuo solução para impressão de conteúdo HTML.

Comments