2012-04-24 174 views
6

我有以下certificate类生产PDF文件的一些图像和数据。设置图像源后,我调用generate()函数并获取test.pdf输出文件。该文档基于QTextDocument类使用setHtml(html)方法创建。如何设置QTextDocument边距和其他属性(setHTML,print to pdf)?

问题是我在文档周围有巨大的空白区域,而我希望带有徽标图像的标题'REPORT'位于页面的顶部。我也想在表格中添加较低的边框,但据我所知它不支持Qt(Supported HTML Subset)。

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) 

我从来没有广泛使用的HTML之前从不与另外,QTextDocument工作,并希望了解有关如何控制文档的页边距和表属性的任何意见。

我想要控制的其他相关属性是分辨率 - 我使用像素图像大小,并需要知道页面和边距大小(像素)。

编辑:这个问题几乎回答@mata。我现在可以设置任何边距和分辨率,但不知道如何控制图像和字体大小。例如。如果我需要一个图像总是50mm宽,并且html标题和主文本字体大小在视觉上是相同的 - 如何实现它?

EDITED2:最后一部分也解决了。这里是由@mata修改后的代码,它给出了相同的结果对于任何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) 
... 

回答

6

您可以指定要在创建QPrinter则在构造函数中使用的分辨率。 然后,在设置页面大小后,您可以在打印机上使用width,heightresolution来找出该值,这里是我得到的Letter(dpi值可以不同,它们取决于屏幕或打印机):

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

您还可以使用setResolution直接设置dpi。 由宽度和高度返回的大小是页面大小(与pageRect()。size()相同),它与纸张大小不一样 - 页面也有页边距,您可以这样设置:

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

这将左右边距设置为12mm,顶部到16mm和底部到20mm - 例如,如果您想要较少的空白空间,您显然可以使用较小的值。 你应该文件大小设置为所产生的大小尺寸:

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

因为你已经注意到自己,HTML和CSS允许的子集是非常有限的,特别是格式化的表格。但不是在桌子上使用较低的边框,您可以使用小时,这可能看起来像你想要的。 至少它看起来并不坏,如果我测试它是这样的:

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

谢谢你的一个很好的例子!我是对的,通过改变分辨率,所有的字体大小都会改变?至少我从96到200的分辨率看到不同之处。有什么方法可以使相对大小的一切?或者我应该使用绝对大小,并始终从页面大小重新计算它们? 'pageRect()'是否包含边距(以像素为单位)的文本的大小?为什么将图像宽度更改为“30%”使其变得如此奇怪(页面外)? – Katya 2012-04-26 12:34:16

+0

- 是的,更改dpi将导致文本和图像相对于页面的大小不同,因为元素的大小(以像素为单位)保持不变,同时每页有更多像素。 - 似乎qt-html中的大小属性必须是绝对的,文档中也没有提及相对图像大小。这就是为什么它看起来不正确。 - 'pageRect()'返回当你从'paperRect()'(在_DevicePixel_)中减去边距时得到的结果。 – mata 2012-04-26 15:26:59

+0

如果你想使用更灵活的HTML,那么你可以使用QWebView(如果安装了QtWebKit)来渲染HTML,尽管渲染可能会慢得多 - 这可能是一个问题,它试图打印页面之前完全呈现。 – mata 2012-04-26 15:33:12