2

I am trying to use Qt for creating a WYSIWYG word processor, focusing mainly on the layout of pages and pagination of a document.

The first thing I'm trying to focus on is a printing preview feature and I thought I would use a QGraphicsScene/View along with a QGraphicsTextItem.

The current problem is that I am unable to contain the text within the confines of the QGraphicsTextItem. The text keeps going until it hits the bottom of the QGraphicsScene/View.Preview

I am wondering if using QGraphics is the correct way to go about it and if so, what should I do to get pagination for my text document?

Code (PyQt, but I should be able to understand C++ even though Python is preferred) for producing the result showed in the attached picture:

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*
jollyroger
  • 659
  • 1
  • 10
  • 19

1 Answers1

1

Qt supports rich text processing by The Scribe framework. It is based on the QTextDocument which is a container for structured rich text documents. The Scribe framework consists of classes for reading and manipulating rich text documents. You can find more about the structured representation of a text document here.

For paginating your document when printing you can convert your text to HTML and render it using QTextDocument, Qt's rich text engine. Although you can perform the drawing and the page breaking by hand, but converting a document to HTML and using QTextDocument to print it is by far the most convenient alternative for printing reports and other complex documents :

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);
}
Nejat
  • 31,784
  • 12
  • 106
  • 138
  • Thank you for your answer. I have been exploring QTextDocument as well, but I have not been able to find a good way to do pagination for QTextDocument instances. Could you please state the basic idea behind paginating a QTextDocument instance? – jollyroger Aug 04 '14 at 14:35
  • @jollyroger The answer is updated to show how to paginate using a `QTextDocument`. – Nejat Aug 04 '14 at 15:12
  • I tried to copy your example, but the only thing that happened was that I made a physical paper printout of the text. This is not at all what I was looking for. I need to have the virtual pages displayed on screen and the printDialog didn't even have this in place. – jollyroger Aug 04 '14 at 19:44
  • @jollyroger You are right, The answer is updated. It uses `QPrintPreviewDialog` to show the preview of the print. – Nejat Aug 05 '14 at 03:14
  • Thank you for the update. You are showing me many things about Qt I find interesting and valuable to know about. I apologize if my initial question was unclear, but what I want to learn is how to implement something like the QPrintPreviewDialog myself. I'll try to have a look in the source code, but I would really appreciate someone telling me the basic idea of how to implement a print preview. – jollyroger Aug 05 '14 at 07:54