在另一个问题中,我了解了QTextDocument,我was told说你可以在同一页上使用QPainter和QTextDocument。但是,当我尝试这样做时,它们各自重新启动文档,擦除对方的内容。
from PySide6.QtGui import QPdfWriter, QPainter, QPageSize, QTextDocument, Qt
from PySide6.QtWidgets import QApplication
def main():
app = QApplication()
pdf = QPdfWriter('example.pdf')
pdf.setPageSize(QPageSize.Letter)
# Whichever of these goes second, overwrites the first.
draw_diagram(pdf)
print_document(pdf)
app.exit(0)
def draw_diagram(pdf: QPdfWriter):
painter = QPainter(pdf)
painter.drawArc(painter.window().width()//4,
painter.window().height()//2 - painter.window().width()//4,
painter.window().width()//2,
painter.window().width()//2,
0,
5760)
painter.drawText(0,
painter.window().height()//2,
painter.window().width(),
painter.window().height()//10,
Qt.AlignHCenter | Qt.AlignTop,
'https://donkirkby.github.io')
print(pdf.newPage())
painter.drawText(painter.window().width()//2,
painter.window().height()//2,
'Bar')
print(pdf.newPage())
painter.end()
def print_document(pdf: QPdfWriter):
html = "<a href='https://donkirkby.github.io'>donkirkby.github.io</a>"
document = QTextDocument()
document.setHtml(html)
document.print_(pdf)
main()理想情况下,我希望文本和绘图在同一页上,但是这段代码试图将它们分开,这样它们就不会相互覆盖。这两种方式都不起作用。
如何将图形与文本文档合并?QTextCursor有帮助吗?
发布于 2021-08-15 17:16:30
问题是,每次设置QPainter时,QPdfWriter都会被重置。一种可能的解决方案是使用相同的QPainter,而不是应该使用drawContents的print方法,您还必须手动处理分页。
from PySide6.QtGui import QPdfWriter, QPainter, QPageSize, QTextDocument, Qt
from PySide6.QtWidgets import QApplication
def main():
app = QApplication()
pdf = QPdfWriter("example.pdf")
pdf.setPageSize(QPageSize.Letter)
painter = QPainter(pdf)
draw_diagram(painter, pdf)
print_document(painter, pdf)
painter.end()
def draw_diagram(painter: QPainter, pdf: QPdfWriter):
painter.drawArc(
painter.window().width() // 4,
painter.window().height() // 2 - painter.window().width() // 4,
painter.window().width() // 2,
painter.window().width() // 2,
0,
5760,
)
painter.drawText(
0,
painter.window().height() // 2,
painter.window().width(),
painter.window().height() // 10,
Qt.AlignHCenter | Qt.AlignTop,
"https://donkirkby.github.io",
)
print(pdf.newPage())
painter.drawText(
painter.window().width() // 2, painter.window().height() // 2, "Bar"
)
print(pdf.newPage())
def print_document(painter: QPainter, pdf: QPdfWriter):
document = QTextDocument()
document.documentLayout().setPaintDevice(pdf)
html = "<a href='https://donkirkby.github.io'>donkirkby.github.io</a>"
document.setHtml(html)
document.drawContents(painter)
if __name__ == "__main__":
main()发布于 2021-08-15 22:37:12
虽然我最终使用了从document.print_()切换到document.drawContents()的eyllanesc's answer,但我也尝试了QTextCursor和QPyTextObject。这个TextObject example给出了一个很好的介绍。我想,如果我需要跨多个页面,它会很有用。
下面是转换为使用QPyTextObject的问题的示例
from PySide6.QtCore import QSizeF, QRectF
from PySide6.QtGui import (QPdfWriter, QPainter, QPageSize, QTextDocument, Qt, QPyTextObject, QTextFormat, QTextCursor,
QTextCharFormat)
from PySide6.QtWidgets import QApplication
DIAGRAM_TEXT_FORMAT = QTextFormat.UserObject + 1
DIAGRAM_DATA = 1
OBJECT_REPLACEMENT = chr(0xfffc)
def main():
app = QApplication()
pdf = QPdfWriter('example.pdf')
pdf.setPageSize(QPageSize.Letter)
print_document(pdf)
app.exit(0)
class Diagram(QPyTextObject):
def __init__(self, parent=None):
super().__init__(parent)
# noinspection PyPep8Naming,PyShadowingBuiltins
def intrinsicSize(self,
doc: QTextDocument,
posInDocument: int,
format: QTextFormat) -> QSizeF:
diameter = doc.textWidth()/4
return QSizeF(doc.textWidth(), diameter)
# noinspection PyPep8Naming,PyShadowingBuiltins
def drawObject(self,
painter: QPainter,
rect: QRectF,
doc: QTextDocument,
posInDocument: int,
format: QTextFormat):
diameter = rect.height()
message = format.property(DIAGRAM_DATA)
painter.drawArc((rect.width() - diameter) // 2,
rect.y(),
diameter,
diameter,
0,
5760)
painter.drawText(rect,
Qt.AlignHCenter | Qt.AlignVCenter,
message)
def print_document(pdf: QPdfWriter):
html = """\
<h1>Title</h1>
<p>Lorem ipsum
<a href='https://donkirkby.github.io'>donkirkby.github.io</a>
dolores sit amet.</p>
"""
document = QTextDocument()
document.setPageSize(QSizeF(pdf.width(), pdf.height()))
font = document.defaultFont()
font.setPixelSize(pdf.height()//60)
document.setDefaultFont(font)
diagram_handler = Diagram()
doc_layout = document.documentLayout()
doc_layout.registerHandler(DIAGRAM_TEXT_FORMAT, diagram_handler)
document.setHtml(html)
cursor = QTextCursor(document)
cursor.movePosition(cursor.End)
cursor.insertText('\n')
diagram_format = QTextCharFormat()
diagram_format.setObjectType(DIAGRAM_TEXT_FORMAT)
for i in range(1, 11):
cursor.insertHtml(f'<h3>Heading {i}</h3>')
cursor.insertText('\n')
diagram_format.setProperty(DIAGRAM_DATA, f'Message {i} in a circle')
cursor.insertText(OBJECT_REPLACEMENT, diagram_format)
document.print_(pdf)
main()我仍然不喜欢这种方法的一点是,可以在标题和图表之间添加分页符。我会问一个关于这个问题的后续问题。
https://stackoverflow.com/questions/68792928
复制相似问题