How to use QPrinter and QPrintPreviewDialog

前端 未结 2 1956
自闭症患者
自闭症患者 2021-01-03 02:53

I want to preview, and then print, a report through a printer using PyQt. I tried the following code :

printer = QtGui.QPrinter()
doc  = QtGui.QTextDocument(         


        
相关标签:
2条回答
  • 2021-01-03 03:34

    A PyQt5 update to the example by ekhumoro providing print preview and print for a Chart:

    from PyQt5 import QtChart, QtCore, QtGui, QtPrintSupport, QtWidgets 
    import sys
    import random
    
    class Window(QtWidgets.QWidget):
        def __init__(self):
            QtWidgets.QWidget.__init__(self)
            self.setWindowTitle(self.tr('Chart Printing'))
            self.chart = QtChart.QChart()
            self.chart_view = QtChart.QChartView(self.chart)
            self.chart_view.setRenderHint(QtGui.QPainter.Antialiasing)
            self.buttonPreview = QtWidgets.QPushButton('Preview', self)
            self.buttonPreview.clicked.connect(self.handle_preview)
            self.buttonPrint = QtWidgets.QPushButton('Print', self)
            self.buttonPrint.clicked.connect(self.handle_print)               
            layout = QtWidgets.QGridLayout(self)
            layout.addWidget(self.chart_view, 0, 0, 1, 2)
            layout.addWidget(self.buttonPreview, 1, 0)        
            layout.addWidget(self.buttonPrint, 1, 1)
            self.create_chart()
    
        def create_chart(self):
            self.chart.setTitle("Chart Print Preview and Print Example") 
            for i in range(5):     
                series = QtChart.QLineSeries()     
                series.setName("Line {}".format(i + 1))
                series.append(0, 0)
                for i in range(1, 10):
                    series.append(i, random.randint(1, 9))
                series.append(10, 10)
                self.chart.addSeries(series)
            self.chart.createDefaultAxes() 
    
        def handle_print(self):
            printer = QtPrintSupport.QPrinter(QtPrintSupport.QPrinter.HighResolution)
            dialog = QtPrintSupport.QPrintDialog(printer, self)
            if dialog.exec_() == QtPrintSupport.QPrintDialog.Accepted:
                self.handle_paint_request(printer)
    
        def handle_preview(self):
            dialog = QtPrintSupport.QPrintPreviewDialog()
            dialog.paintRequested.connect(self.handle_paint_request)
            dialog.exec_()
    
        def handle_paint_request(self, printer):
            painter = QtGui.QPainter(printer)
            painter.setViewport(self.chart_view.rect())
            painter.setWindow(self.chart_view.rect())                        
            self.chart_view.render(painter)
            painter.end()
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
        window = Window()
        window.resize(640, 480)
        window.show()
        sys.exit(app.exec_())
    

    Edit: For the above demo code to run on Windows, then it requires:

    > pip install PyQt5  
    > pip install pyqt5-tools   
    > pip install PyQtChart 
    
    0 讨论(0)
  • 2021-01-03 03:35

    Basic demo of Qt's print dialogs:

    PyQt4

    import sys, os
    from PyQt4 import QtGui, QtCore
    
    class Window(QtGui.QWidget):
        def __init__(self):
            super(Window, self).__init__()
            self.setWindowTitle('Document Printer')
            self.editor = QtGui.QTextEdit(self)
            self.editor.textChanged.connect(self.handleTextChanged)
            self.buttonOpen = QtGui.QPushButton('Open', self)
            self.buttonOpen.clicked.connect(self.handleOpen)
            self.buttonPrint = QtGui.QPushButton('Print', self)
            self.buttonPrint.clicked.connect(self.handlePrint)
            self.buttonPreview = QtGui.QPushButton('Preview', self)
            self.buttonPreview.clicked.connect(self.handlePreview)
            layout = QtGui.QGridLayout(self)
            layout.addWidget(self.editor, 0, 0, 1, 3)
            layout.addWidget(self.buttonOpen, 1, 0)
            layout.addWidget(self.buttonPrint, 1, 1)
            layout.addWidget(self.buttonPreview, 1, 2)
            self.handleTextChanged()
    
        def handleOpen(self):
            path = QtGui.QFileDialog.getOpenFileName(
                self, 'Open file', '',
                'HTML files (*.html);;Text files (*.txt)')
            if path:
                file = QtCore.QFile(path)
                if file.open(QtCore.QIODevice.ReadOnly):
                    stream = QtCore.QTextStream(file)
                    text = stream.readAll()
                    info = QtCore.QFileInfo(path)
                    if info.completeSuffix() == 'html':
                        self.editor.setHtml(text)
                    else:
                        self.editor.setPlainText(text)
                    file.close()
    
        def handlePrint(self):
            dialog = QtGui.QPrintDialog()
            if dialog.exec_() == QtGui.QDialog.Accepted:
                self.editor.document().print_(dialog.printer())
    
        def handlePreview(self):
            dialog = QtGui.QPrintPreviewDialog()
            dialog.paintRequested.connect(self.editor.print_)
            dialog.exec_()
    
        def handleTextChanged(self):
            enable = not self.editor.document().isEmpty()
            self.buttonPrint.setEnabled(enable)
            self.buttonPreview.setEnabled(enable)
    
    if __name__ == '__main__':
    
        app = QtGui.QApplication(sys.argv)
        window = Window()
        window.resize(640, 480)
        window.show()
        sys.exit(app.exec_())
    

    PyQt5

    import sys, os
    from PyQt5 import QtCore, QtWidgets, QtPrintSupport
    
    class Window(QtWidgets.QWidget):
        def __init__(self):
            super(Window, self).__init__()
            self.setWindowTitle('Document Printer')
            self.editor = QtWidgets.QTextEdit(self)
            self.editor.textChanged.connect(self.handleTextChanged)
            self.buttonOpen = QtWidgets.QPushButton('Open', self)
            self.buttonOpen.clicked.connect(self.handleOpen)
            self.buttonPrint = QtWidgets.QPushButton('Print', self)
            self.buttonPrint.clicked.connect(self.handlePrint)
            self.buttonPreview = QtWidgets.QPushButton('Preview', self)
            self.buttonPreview.clicked.connect(self.handlePreview)
            layout = QtWidgets.QGridLayout(self)
            layout.addWidget(self.editor, 0, 0, 1, 3)
            layout.addWidget(self.buttonOpen, 1, 0)
            layout.addWidget(self.buttonPrint, 1, 1)
            layout.addWidget(self.buttonPreview, 1, 2)
            self.handleTextChanged()
    
        def handleOpen(self):
            path = QtWidgets.QFileDialog.getOpenFileName(
                self, 'Open file', '',
                'HTML files (*.html);;Text files (*.txt)')[0]
            if path:
                file = QtCore.QFile(path)
                if file.open(QtCore.QIODevice.ReadOnly):
                    stream = QtCore.QTextStream(file)
                    text = stream.readAll()
                    info = QtCore.QFileInfo(path)
                    if info.completeSuffix() == 'html':
                        self.editor.setHtml(text)
                    else:
                        self.editor.setPlainText(text)
                    file.close()
    
        def handlePrint(self):
            dialog = QtPrintSupport.QPrintDialog()
            if dialog.exec_() == QtWidgets.QDialog.Accepted:
                self.editor.document().print_(dialog.printer())
    
        def handlePreview(self):
            dialog = QtPrintSupport.QPrintPreviewDialog()
            dialog.paintRequested.connect(self.editor.print_)
            dialog.exec_()
    
        def handleTextChanged(self):
            enable = not self.editor.document().isEmpty()
            self.buttonPrint.setEnabled(enable)
            self.buttonPreview.setEnabled(enable)
    
    if __name__ == '__main__':
    
        app = QtWidgets.QApplication(sys.argv)
        window = Window()
        window.resize(640, 480)
        window.show()
        sys.exit(app.exec_())
    

    EDIT

    To print-preview a graphics view, use its render method:

    def handlePreview(self):
        # dialog = QtPrintSupport.QPrintPreviewDialog() # PyQt5
        dialog = QtGui.QPrintPreviewDialog()
        dialog.paintRequested.connect(self.handlePaintRequest)
        dialog.exec_()
    
    def handlePaintRequest(self, printer):
        self.view.render(QtGui.QPainter(printer))
    
    0 讨论(0)
提交回复
热议问题