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

2 投票
1 回答
701 浏览
提问于 2025-04-18 15:55

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

我现在想要重点实现的是打印预览功能,我打算使用QGraphicsScene和QGraphicsTextItem来实现这个功能。

目前遇到的问题是,我无法把文本限制在QGraphicsTextItem的范围内。文本一直延伸,直到碰到QGraphicsScene的底部。预览

我在想,使用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 个回答

1

Qt通过Scribe框架支持丰富的文本处理。这个框架是基于QTextDocument的,后者是用来存放结构化的丰富文本文档的容器。Scribe框架包含了一些类,用于读取和操作丰富文本文档。你可以在这里了解更多关于文本文档结构化表示的信息。

如果你想在打印时对文档进行分页,可以将文本转换为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);
}

撰写回答