2012-04-24 31 views
6

Tengo la siguiente clase certificate para producir documentos en formato PDF a partir de algunas imágenes y datos. Después de configurar las fuentes de imagen, llamo a la función generate() y obtengo el archivo de salida test.pdf. El documento se crea en base a la clase QTextDocument utilizando el método setHtml(html).Cómo establecer los márgenes de QTextDocument y otras propiedades (setHTML, print to pdf)?

El problema es que tengo grandes espacios en blanco alrededor del documento, mientras que quiero que el título 'INFORMAR' con la imagen del logotipo esté en la parte superior de la página. También me gustaría agregar un borde inferior a la tabla, pero según tengo entendido, Qt no lo admite (Supported HTML Subset).

código python3:

class certificate: 

def __init__(self): 
    self.logo = None 
    pdffile = 'test.pdf' 
    self.histogram = None 
    self.printer = QPrinter() 
    self.printer.setPageSize(QPrinter.Letter) 
    self.printer.setOutputFormat(QPrinter.PdfFormat) 
    self.printer.setOutputFileName(pdffile) 

def generate(self): 
    document = QTextDocument() 
    html = "" 
    html += ('<head><title>Report</title><style></style></head>' 
       '<body><table width="100%"><tr>' 
        '<td><img src="{}" width="30"></td>' 
        '<td><h1>REPORT</h1></td>' 
       '</tr></table>' 
       '<p align=right><img src="{}" width="300"></p>' 
       '<p align=right>Sample</p></body>').format(self.logo, self.histogram) 
    document.setHtml(html) 
    document.print_(self.printer) 

nunca utiliza ampliamente html antes y nunca trabajó con QTextDocument, y agradecería cualquier consejo sobre cómo controlar los márgenes del documento y propiedades de la tabla.

Otra propiedad relacionada que deseo controlar es la resolución: utilizo el tamaño de la imagen en píxeles y necesito conocer los tamaños de página y margen en píxeles.

EDITADO: Casi la pregunta es respondida por @mata. Ahora puedo establecer los márgenes y la resolución, pero no entiendo cómo controlar los tamaños de las imágenes y las fuentes. P.ej. si necesito que una imagen tenga siempre 50 mm de ancho, y los tamaños de fuente del encabezado html y del texto principal son visualmente iguales, ¿cómo implementarlo?

EDITED2: La última parte se solucionó también. Aquí está modificado por código @mata, se da el mismo resultado para cualquier valor dpi:

dpi=96 

document = QTextDocument() 
html = """ 
<head> 
    <title>Report</title> 
    <style> 
    </style> 
</head> 
<body> 
    <table width="100%"> 
     <tr> 
      <td><img src="{0}" width="{1}"></td> 
      <td><h1>REPORT</h1></td> 
     </tr> 
    </table> 
    <hr> 
    <p align=right><img src="{2}" width="{3}"></p> 
    <p align=right>Sample</p> 
</body> 
""".format('D:\Documents\IST Projects\diashape\docbook\Installation\images\istlogo_medium.png', 
       40*dpi/96, 
       'D:\Documents\IST Projects\diashape\docbook\Installation\images\istlogo_medium.png', 
       200*dpi/96) 

document.setHtml(html) 

printer = QPrinter() 
font = QFont() 
font.setPointSize(12*dpi/96) 
document.setDefaultFont(font) 
printer.setResolution(dpi) 
... 

Respuesta

6

Puede especificar lo que la resolución que desea utilizar en el constructor cuando se crea la QPrinter. A continuación, después de configurar el tamaño de página, puede utilizar width, height y resolution de la impresora para fint que los valores, esto es lo que me dieron por Carta (DPI-valores pueden ser diferentes, que dependen de la pantalla o la impresora):

QPrinter(QPrinter.ScreenResolution) # 96dpi, 752x992 
QPrinter(QPrinter.PrinterResolution) # 72dpi, 564x744 
QPrinter(QPrinter.HighResolution)  # 1200dpi, 9400x12400 

también puede establecer los puntos por pulgada directamente utilizando setResolution. El tamaño devuelto por ancho y alto es el tamaño de página (igual que pageRect(). Size()), que no es lo mismo que el tamaño de papel, ya que la página también tiene márgenes, que puede establecer así:

printer.setPageMargins(12, 16, 12, 20, QPrinter.Millimeter) 

esto establece los márgenes izquierdo y derecho a 12 mm, de arriba a 16 mm y de abajo a 20 mm; por ejemplo, si quiere menos espacio en blanco, obviamente puede usar valores más pequeños. Y usted debe configurar el tamaño del documento al tamaño del tamaño resultante:

document.setPageSize(QSizeF(printer.pageRect().size())) 

como usted ha notado usted mismo, el subconjunto de HTML y CSS permitido es muy limitado, especialmente para el formato de tablas. Pero en lugar de usar un borde inferior en la mesa, puedes usar una hora, que probablemente se verá como la quieres. Al menos no se ve tan mal si lo pruebo así:

from PyQt4.QtGui import * 
from PyQt4.QtCore import * 

a=QApplication([]) 
document = QTextDocument() 
html = """ 
<head> 
    <title>Report</title> 
    <style> 
    </style> 
</head> 
<body> 
    <table width="100%"> 
     <tr> 
      <td><img src="{}" width="30"></td> 
      <td><h1>REPORT</h1></td> 
     </tr> 
    </table> 
    <hr> 
    <p align=right><img src="{}" width="300"></p> 
    <p align=right>Sample</p> 
</body> 
""".format('', '') 

document.setHtml(html) 

printer = QPrinter() 
printer.setResolution(96) 
printer.setPageSize(QPrinter.Letter) 
printer.setOutputFormat(QPrinter.PdfFormat) 
printer.setOutputFileName("test.pdf") 
printer.setPageMargins(12, 16, 12, 20, QPrinter.Millimeter) 
document.setPageSize(QSizeF(printer.pageRect().size())) 
print(document.pageSize(), printer.resolution(), printer.pageRect()) 

document.print_(printer) 
+0

¡Gracias por un buen ejemplo! ¿Tengo razón en que al cambiar la resolución, cambian todos los tamaños de fuente?Al menos veo la diferencia cuando cambio de una resolución de 96 a 200. ¿Hay alguna manera de hacer todo en tamaño relativo? ¿O debería usar tamaños absolutos y siempre volver a calcularlos desde el tamaño de página? ¿'PageRect()' es el tamaño del rect con texto sin márgenes (en píxeles)? ¿Por qué cambiar el ancho de la imagen a "30%" lo hace tan extraño (fuera de página)? – Katya

+0

- sí, cambiar los ppp dará como resultado que el texto y las imágenes tengan un tamaño diferente al de la página, ya que el tamaño de los elementos (en píxeles) se mantiene igual mientras que hay más píxeles por página. - parece que los atributos de tamaño en el qt-html deben ser absolutos, tampoco se menciona el tamaño relativo de las imágenes en la documentación. es por eso que no se ve bien. - 'pageRect()' devuelve lo que obtienes al restar los márgenes de 'paperRect()' (en _DevicePixel_). – mata

+0

si quisiera utilizar html más flexible, entonces podría usar QWebView (de QtWebKit si está instalado) para renderizar el html, aunque el renderizado probablemente sea mucho más lento, lo que podría ser un problema si intenta imprimir la página antes de que sea completamente renderizado. – mata

Cuestiones relacionadas