Как установить поля QTextDocument и другие свойства (setHTML, print to pdf)?

у меня есть следующие certificate класс для создания pdf-документа из некоторых изображений и данных. После установки источников изображения я вызываю generate() функция и получить тест.выходной файл PDF. Документ создается на основе QTextDocument класс с помощью setHtml(html) метод.

проблема в том, что у меня есть огромные пробелы вокруг документа, в то время как я хочу, чтобы заголовок "отчет" с изображением логотипа был в самой верхней части страницы. Я также хотел бы добавить нижнюю границу в таблицу, но, как я понимаю он не поддерживается Qt ( поддерживается подмножество HTML).

код 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. Теперь я могу установить любые поля и разрешение, но не понимаю, как управлять размером изображения и шрифта. Например. если мне нужно, чтобы изображение всегда было шириной 50 мм, а 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:DocumentsIST ProjectsdiashapedocbookInstallationimagesistlogo_medium.png',
              40*dpi/96, 
              'D:DocumentsIST ProjectsdiashapedocbookInstallationimagesistlogo_medium.png', 
              200*dpi/96)

document.setHtml(html)

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

1 ответов


вы можете указать, какое разрешение вы хотите использовать в конструкторе при создании QPrinter. Затем, после установки размера страницы, вы можете использовать width, height и resolution на принтере, чтобы найти эти значения, вот что я получил для письмо (Дои-значения могут быть разными, они зависят от экрана или принтера):

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

вы также можете установить dpi напрямую с помощью setResolution. Размер, возвращаемый по ширине и высоте, - это размер страницы (такой же, как pageRect().размер()), который не совпадает с размером бумаги - так как страница также имеет поля, которые вы можете установить следующим образом:

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

это устанавливает левое и правое поля до 12 мм, сверху до 16 мм и снизу до 20 мм - например, если вы хотите меньше белого пространства, вы можете просто использовать меньшие значения. И вы должны установить размер документа размер размер:

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

как вы сами заметили, подмножество html и css разрешено очень ограничено, специально для форматирования таблиц. Но вместо использования нижней границы на столе вы можете просто использовать hr, который, вероятно, будет выглядеть так, как вы хотите. По крайней мере, это не выглядит так плохо, если я тестирую его так:

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)