QGraphicsTextItem的分页:将文本限制在特定的矩形区域

Posted

技术标签:

【中文标题】QGraphicsTextItem的分页:将文本限制在特定的矩形区域【英文标题】:Pagination of QGraphicsTextItem: Confining text to a specific rectangular area 【发布时间】:2014-08-04 13:46:47 【问题描述】:

我正在尝试使用 Qt 来创建一个所见即所得的文字处理器,主要关注页面的布局和文档的分页。

我首先要关注的是打印预览功能,我想我会使用 QGraphicsScene/View 和 QGraphicsTextItem。

当前的问题是我无法将文本包含在 QGraphicsTextItem 的范围内。文本一直持续到它到达 QGraphicsScene/View 的底部。

我想知道使用 QGraphics 是否是正确的方法,如果是,我应该怎么做才能让我的文本文档分页?

生成附图所示结果的代码(PyQt,但我应该能够理解 C++,即使 Python 是首选):

import sys

from PyQt4.QtGui import \
QApplication, \
QDialog, \
QGraphicsScene, \
QGraphicsView, \
QVBoxLayout, \
QPainter

from PyQt4.QtCore import \
QRectF, \
Qt


class GraphicsView(QGraphicsView):
    def __init__(self, fname='', parent=None):
        super(GraphicsView, self).__init__(parent)
        self.setDragMode(QGraphicsView.RubberBandDrag)
        self.setRenderHint(QPainter.Antialiasing)
        self.setRenderHint(QPainter.TextAntialiasing)

    def wheelEvent(self, event):
        factor = 1.41 ** (-event.delta() / 240.0)
        self.scale(factor, factor)


class Editor(QDialog):

    def __init__(self, parent=None):
        super(Editor, self).__init__(parent)

        pageSize = (842, 198)
        f = open('alotbsol.txt')
        txt = f.read()

        view = GraphicsView()
        scene = QGraphicsScene(self)
        scene.setSceneRect(0, 0, pageSize[0], pageSize[1])
        rect = QRectF(0, 0, pageSize[0], pageSize[1])
        scene.addRect(rect, Qt.black)
        textbox = scene.addText(txt)
        textbox.setTextWidth(pageSize[0])
        view.setScene(scene)

        layout = QVBoxLayout()
        layout.addWidget(view, 1)
        self.setLayout(layout)

        self.resize(scene.width() + 50, scene.height() * 2)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    widget = Editor()
    widget.show()
    app.exec_()*emphasized text*

【问题讨论】:

【参考方案1】:

Qt 支持The Scribe framework 处理富文本。它基于QTextDocument,它是结构化富文本文档的容器。 Scribe 框架由用于阅读和操作富文本文档的类组成。你可以找到更多关于文本文档的结构化表示here。

为了在打印时对文档进行分页,您可以将文本转换为 html 并使用 Qt 的富文本引擎 QTextDocument 呈现它。虽然您可以手动执行绘图和分页,但将文档转换为 HTML 并使用QTextDocument 打印它是迄今为止打印报告和其他复杂文档最方便的替代方法:

void Dialog::Print(QString myText)


    QPrinter printer;

    QString html = QString("<P>%1</P>").arg(myText);

    QPrintDialog printDialog(&printer, this);
    if (printDialog.exec()) 
        textDocument.setHtml(html);

        QPrintPreviewDialog preview(&printer, this);
        preview.setWindowFlags ( Qt::Window );
        connect(&preview, SIGNAL(paintRequested(QPrinter *)), SLOT(printPreview(QPrinter *)));
        preview.exec();
    



void Dialog::printPreview(QPrinter * printer)

    textDocument.print(printer);

【讨论】:

感谢您的回答。我也一直在探索 QTextDocument ,但我一直无法找到为 QTextDocument 实例进行分页的好方法。您能否说明分页 QTextDocument 实例背后的基本思想? @jollyroger 答案已更新以显示如何使用QTextDocument 进行分页。 我试图复制您的示例,但唯一发生的事情是我制作了文本的物理纸打印输出。这根本不是我想要的。我需要在屏幕上显示虚拟页面,而 printDialog 甚至都没有。 @jollyroger 你是对的,答案已更新。它使用QPrintPreviewDialog 来显示打印的预览。 感谢您的更新。你向我展示了很多关于 Qt 的东西,我觉得很有趣并且很有价值。如果我最初的问题不清楚,我深表歉意,但我想学习的是如何自己实现 QPrintPreviewDialog 之类的东西。我将尝试查看源代码,但我非常感谢有人告诉我如何实现打印预览的基本概念。

以上是关于QGraphicsTextItem的分页:将文本限制在特定的矩形区域的主要内容,如果未能解决你的问题,请参考以下文章

如何将刷卡器中的分页项目符号更改为文本?

Android中的分页文本

Python:argparse 帮助文本的分页?

更改 QGraphicsTextItem 内文本的突出显示颜色

页面设置中“分页符”和“下一页”的区别是啥?

JQuery Mobile 中的分页符?