2012-04-24 9 views
6

Ho la seguente classe certificate per la produzione di documenti PDF da alcune immagini e dati. Dopo aver impostato le fonti di immagini, chiamo la funzione generate() e il file di output test.pdf. Il documento viene creato in base alla classe QTextDocument utilizzando il metodo setHtml(html).Come impostare i margini di QTextDocument e altre proprietà (setHTML, print to pdf)?

Il problema è che ho enormi spazi bianchi attorno al documento, mentre voglio che il titolo "REPORT" con l'immagine del logo sia nella parte superiore della pagina. Vorrei anche aggiungere il bordo inferiore al tavolo, ma come ho capito non è supportato da Qt (Supported HTML Subset).

codice 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) 

ho mai usato ampiamente html prima e mai lavorato con QTextDocument, e apprezzerebbe qualche consiglio su come controllare margini del documento e le proprietà di tabella.

Un'altra proprietà correlata che desidero controllare è la risoluzione: utilizzo la dimensione dell'immagine dei pixel e ho bisogno di conoscere le dimensioni della pagina e dei margini in pixel.

MODIFICATO: La domanda viene quasi risposta da @mata. Ora posso impostare qualsiasi margine e risoluzione, ma non capisco come controllare l'immagine e le dimensioni dei caratteri. Per esempio. se ho bisogno che un'immagine sia sempre larga 50mm, e l'intestazione HTML e le dimensioni dei caratteri del testo principale sono visivamente le stesse - come implementarlo?

EDITED2: Anche l'ultima parte è stata risolta. Qui viene modificato il codice da @mata, dà lo stesso risultato per qualsiasi valore 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) 
... 

risposta

6

È possibile specificare quale risoluzione che si desidera utilizzare nel costruttore quando si crea il QPrinter. Quindi dopo aver impostato la pagine, è possibile utilizzare width, height e resolution sulla stampante per estrarre quei valori, ecco cosa ho ottenuto per Lettera (i valori dpi possono essere diversi, dipendono dallo schermo o dal stampante):

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

È anche possibile impostare il dpi direttamente utilizzando setResolution. La dimensione restituita dalla larghezza e dall'altezza è la dimensione della pagina (uguale a pageRect(). Size()), che non è uguale al formato della carta, poiché la pagina presenta anche margini che è possibile impostare in questo modo:

imposta i margini sinistro e destro su 12 mm, superiore a 16 mm e inferiore a 20 mm - solo per esempio, se si desidera meno spazio bianco, è ovviamente possibile utilizzare solo valori più piccoli. E si dovrebbe impostare il formato del documento alle dimensioni del formato risultante:

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

come hai notato tu stesso, il sottoinsieme di HTML e CSS permesso è molto limitata, specialmente per la formattazione tabelle. Ma invece di usare un bordo inferiore sul tavolo potresti usare solo un hr, che probabilmente assomiglierà a te. Almeno non sembra così male se lo provo in questo modo:

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

Grazie per un ottimo esempio! Ho ragione che cambiando la risoluzione tutte le dimensioni dei caratteri cambiano?Almeno vedo la differenza quando cambio da 96 a 200 risoluzione. C'è un modo per fare tutto in dimensioni relative? O dovrei usare le dimensioni assolute e ricalcolarle sempre dalla dimensione della pagina? È 'pageRect()' la dimensione del rect con testo esclusi i margini (in pixel)? Perché cambiare la larghezza dell'immagine in "30%" lo rende così strano (fuori dalla pagina)? – Katya

+0

- sì, cambiando il dpi il testo e le immagini saranno di dimensioni diverse rispetto alla pagina, poiché la dimensione degli elementi (in pixel) rimane invariata mentre non ha più pixel per pagina. - sembra che gli attributi di dimensione nel qt-html debbano essere assoluti, inoltre non c'è menzione delle dimensioni relative dell'immagine nella documentazione. è per questo che non sembra giusto. - 'pageRect()' restituisce ciò che si ottiene quando si sottraggono i margini da 'paperRect()' (in _DevicePixel_). – mata

+0

se si volesse usare un html più flessibile, allora si potrebbe usare un QWebView (da QtWebKit se installato) per rendere l'html, anche se il rendering probabilmente sarà molto più lento - il che potrebbe essere un problema se si tenta di stampare la pagina prima che sia completamente reso. – mata

Problemi correlati