[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pykde
Subject:    [PyQt] Printing QGraphicsScene on printer or pdf file format.
From:       Aleksandar Nedeljkovic <sasko2909 () gmail ! com>
Date:       2015-07-18 5:08:32
Message-ID: CAE3nOCQH5Bx=X=uOSCZLy+dferv66qO__A21Anf-5gHoh_ADzQ () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Hi,

I made an application that uses QGraphicsScene to show some reports. After
that I use QGraphicsScene.render() and QPainter to print content of
QGraphicsScene to printer or pdf file.

And I got confused, because on Centos 6 it all works fine, but on Windows 7
letters are not positioned nicely, different from the contents of
QGraphicsScene.

I made some small test script (in attachment) that does described work.
There is also result of printing of content of QGraphicsScene in pdf file
in Centos 6 (good) and Windows 7 (not good).

Can anybody tell me what I am doing wrong, or is this some problem specific
for Windows. And is there anything that I can do to fix this.

Thanks in advance.

[Attachment #5 (text/html)]

<div dir="ltr"><div><div><div><div><div>Hi,<br><br></div>I made an application that \
uses QGraphicsScene to show some reports. After that I use QGraphicsScene.render() \
and QPainter to print content of QGraphicsScene to printer or pdf \
file.<br><br></div>And I got confused, because on Centos 6 it all works fine, but on \
Windows 7 letters are not positioned nicely, different from the contents of \
QGraphicsScene.<br><br></div>I made some small test script (in attachment) that does \
described work. There is also result of printing of content of QGraphicsScene in pdf \
file in Centos 6 (good) and Windows 7 (not good).<br><br></div>Can anybody tell me \
what I am doing wrong, or is this some problem specific for Windows. And is there \
anything that I can do to fix this.<br><br></div>Thanks in advance.<br></div>


["Report20150718Centos6.pdf" (application/pdf)]
["Report20150718Windows7.pdf" (application/pdf)]
["testreport.py" (text/x-python)]

#!/usr/bin/python

#areareport.py

##import sys
from datetime import date

from PyQt4.QtGui import QDialog, QLabel, QComboBox, QGraphicsScene, \
     QGraphicsView, QPushButton, QHBoxLayout, QGridLayout, QPrinter, \
     QGraphicsRectItem, QGraphicsTextItem, QFont, QPrintDialog, QPainter, \
     QMessageBox, QBrush, QFileDialog, QApplication
from PyQt4.QtCore import QPointF, SIGNAL, QDate, QRectF, Qt

PAGESIZEX = 794
PAGESIZEY = 1123 
PAGEMARGINX = 57
PAGEMARGINY = 57
OFFSETX = 25
OFFSETY = 25

################################################################################
#                                                                              #
#                                                                              #
################################################################################


class BaseReportDialog(QDialog):
    """
        Base class for all reports (archive and current). All common operations 
        are handled here.
    """
    def __init__(self, parent = None):
        super(BaseReportDialog, self).__init__(parent)
        self.position = QPointF(57, 57)
        self.pageNumber = 0
        self.tableIndex = 1

        self.scene = QGraphicsScene()
        self.scene.setItemIndexMethod(QGraphicsScene.NoIndex)
        self.view = QGraphicsView()
        self.view.setScene(self.scene)
##        self.view.setRenderHint(QPainter.Antialiasing)
        self.view.setBackgroundBrush(QBrush(Qt.lightGray))

        self.setFixedWidth(1000)

        saveButton = QPushButton("Save")
        finishButton = QPushButton("Finish")
        printButton = QPushButton("Print")

        self.connect(saveButton, SIGNAL("clicked()"), self.savePDF)
        self.connect(printButton, SIGNAL("clicked()"), self.printReport)
        self.connect(finishButton, SIGNAL("clicked()"), self.accept)
        

        buttonLayout = QHBoxLayout()
        buttonLayout.addStretch()
        buttonLayout.addWidget(saveButton)
        buttonLayout.addWidget(printButton)
        buttonLayout.addWidget(finishButton)

        self.mainLayout = QGridLayout()
        self.mainLayout.addWidget(self.view, 2, 1, 1, 2)
        self.mainLayout.addLayout(buttonLayout, 3, 1, 1, 2)
        self.setLayout(self.mainLayout)
        self.setMinimumHeight(650)

        self.printer = QPrinter(QPrinter.ScreenResolution)
        self.restartScene()
##        self.printer.setPageSize(QPrinter.Letter)


    def addPage(self):
        """
            Adds page to report. This function is called when current page is 
            full and it is needed to start new page.
            :param: None
            :returns: None
        """
        self.pageNumber = self.pageNumber + 1
        self.scene.setSceneRect(0, \
                                0, \
                                PAGESIZEX + 2 * OFFSETX, \
                                (PAGESIZEY + 2 * OFFSETY) * self.pageNumber)
        yPosition = (PAGESIZEY + 2 * OFFSETY) * (self.pageNumber - 1) + OFFSETY
##        pageOffsetItem = QGraphicsRectItem(0, \
##                                           yPosition - OFFSETY, \
##                                           PAGESIZEX + 2 * OFFSETX, \
##                                           PAGESIZEY + 2 * OFFSETY)
##        self.scene.addItem(pageOffsetItem)
        pageRectItem = QGraphicsRectItem(OFFSETX, \
                                         yPosition, \
                                         PAGESIZEX, \
                                         PAGESIZEY)
        pageRectItem.setBrush(QBrush(Qt.white))
        self.scene.addItem(pageRectItem)
##        pageMarginItem = QGraphicsRectItem(OFFSETX + PAGEMARGINX, \
##                                           OFFSETY + PAGEMARGINY + \
##                                           (2 * OFFSETY + PAGESIZEY) * \
##                                           (self.pageNumber - 1), \
##                                           PAGESIZEX - PAGEMARGINX * 2, \
##                                           PAGESIZEY - PAGEMARGINY * 2)
##        self.scene.addItem(pageMarginItem)
        textItem = QGraphicsTextItem(str(self.pageNumber))
        timesFont = QFont("Times", 12)
        textItem.setFont(timesFont)
        textItem.setPos((PAGESIZEX - textItem.boundingRect().width()) / 2 + \
                        OFFSETX, \
                        (PAGESIZEY + 2 * OFFSETX) * self.pageNumber - 70)
        self.scene.addItem(textItem)
        redLine = OFFSETY + PAGEMARGINY + (self.pageNumber - 1) * \
                  (PAGESIZEY + 2 * OFFSETY) + PAGESIZEY - 2 * PAGEMARGINY
        self.position.setY((2 * OFFSETY + PAGESIZEY) * (self.pageNumber - 1) + \
                           PAGEMARGINY + OFFSETY)


    def printReport(self):
        """
            Prints report on printer or file.
            :param: None
            :returns: None
        """
##        self.printer.setOutputFormat(QPrinter.PdfFormat)
##        self.printer.setOutputFileName("nonwritable.pdf")
##        self.printer.setFullPage(True)
        self.printer.setPaperSize(QPrinter.A4)
        printDialog = QPrintDialog(self.printer)
        if (printDialog.exec_() == QPrintDialog.Accepted):
            painter = QPainter(self.printer)
##            painter.setRenderHint(QPainter.Antialiasing)
##            painter.setRenderHint(QPainter.TextAntialiasing)
            painter.setRenderHint(QPainter.HighQualityAntialiasing)
            painter.begin(self.printer)
            for i in range(self.pageNumber):
                target = QRectF(0, \
                                0, \
                                self.printer.\
                                paperRect(QPrinter.DevicePixel).width(), \
                                self.printer.\
                                paperRect(QPrinter.DevicePixel).height())
                source = QRectF(OFFSETX, \
                                (PAGESIZEY + OFFSETY * 2) * i + OFFSETY, \
                                PAGESIZEX, \
                                PAGESIZEY)
                self.scene.render(painter, target, source)
                if i != self.pageNumber - 1:
                    self.printer.newPage()
            painter.end()
        

    def setHeaderAndDate(self):
        """
            Sets header of report and date when report is generated.
            :param: None
            :returns: None
        """
        self.position = QPointF(PAGEMARGINX + OFFSETX, PAGEMARGINY + OFFSETY)

        timesFont = QFont("Times", 12)
        self.position.setY(self.position.y() + OFFSETY)
        self.position.setX(self.position.x() + OFFSETX)

        titleText = "This text is not formatted nicely on Windows 7."
        titleTextItem = QGraphicsTextItem(titleText)
        titleTextItem.setFont(timesFont)
        titleTextItem.setPos(self.position)
        self.scene.addItem(titleTextItem)
        self.position.setY(self.position.y() + \
                           1 * titleTextItem.boundingRect().height())

        titleText = "This text is formatted nicely on Centos 6."
        titleTextItem = QGraphicsTextItem(titleText)
        titleTextItem.setFont(timesFont)
        titleTextItem.setPos(self.position)
        self.scene.addItem(titleTextItem)
        self.position.setY(self.position.y() + \
                           1 * titleTextItem.boundingRect().height())
        


    def restartScene(self):
        """
            Restarts scene on which report is generated.
            :param: None
            :returns: None
        """
        self.scene.clear()
        self.pageNumber = 0
        self.scene.setSceneRect(0, \
                                0, \
                                PAGESIZEX + 2 * OFFSETX, \
                                PAGESIZEY + 2 * OFFSETY)
        self.addPage()
        self.setHeaderAndDate()



    def savePDF(self):
        """
            Saves report (archive or current to .pdf file). File name of saved 
            report is determined by parameter fileNameString. This function is 
            called by derived classes.
            :param: fileNameString: String that determines name of file in 
            which report shall be saved.
            :type fileNameString: String
            :returns None:
        """
        fileName = "Report%04d%02d%02d" % \
                   (date.today().year, \
                    date.today().month, \
                    date.today().day)
        fileName = QFileDialog.getSaveFileName(self, "Project Handler - " +\
                                               "Save to PDF", fileName, \
                                               "PDF files (*.pdf)")
        if fileName.isEmpty() == False:
            self.printer.setOutputFormat(QPrinter.PdfFormat)
            self.printer.setOutputFileName(fileName)
            self.printer.setFullPage(True)
            self.printer.setPaperSize(QPrinter.A4)
            painter = QPainter(self.printer)
            painter.setRenderHint(QPainter.Antialiasing)
            painter.setRenderHint(QPainter.TextAntialiasing)
            painter.setRenderHint(QPainter.SmoothPixmapTransform)
            painter.setRenderHint(QPainter.HighQualityAntialiasing)
            painter.setRenderHint(QPainter.NonCosmeticDefaultPen)
            painter.begin(self.printer)
            for i in range(self.pageNumber):
                target = QRectF(0, \
                                0, \
                                self.printer.\
                                paperRect(QPrinter.DevicePixel).width(), \
                                self.printer.\
                                paperRect(QPrinter.DevicePixel).height())
                source = QRectF(OFFSETX, \
                                (PAGESIZEY + OFFSETY * 2) * i + OFFSETY, \
                                PAGESIZEX, \
                                PAGESIZEY)
                self.scene.render(painter, target, source)
                if i != self.pageNumber - 1:
                    self.printer.newPage()
            painter.end()  
        


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    form = BaseReportDialog()
    form.show()
    app.exec_()

[Attachment #9 (text/plain)]

_______________________________________________
PyQt mailing list    PyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic