Search code examples
pythonpyqtpyqt5qprintpreviewdialog

How to prevent Print Button to close QPrintPreviewDialog after printing


When I run this simple program...

import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtPrintSupport import *

class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()

        html = "<html><body>"
        for i in range(1000):
            html += "<p>{i}</p>".format(i=i)
        html += "</body></html>"

        self.document = QTextDocument()
        self.document.setHtml(html)

        closing_checkbox = QCheckBox("Close Print Preview dialog after first print")
        closing_checkbox.setCheckState(Qt.Checked)
        button_preview = QPushButton('Preview', self)
        button_preview.clicked.connect(self.handlePreview)
        layout = QVBoxLayout(self)
        layout.addWidget(closing_checkbox)
        layout.addWidget(button_preview)

    def handlePreview(self):
        dialog = QPrintPreviewDialog()
        dialog.paintRequested.connect(self.document.print_)
        dialog.exec_()

app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())

...after clicking on Preview button, QPrintPreviewDialog opens. After clicking on (far right) Print button on toolbar I choose the printer and it prints and QPrintPreviewDialog closes. I understand that in most cases that is exactly what user wants. But what if in some cases user wants to print the same document again, but on different network printer. Or for example he wants to print pages 1-2 first and after that (with the same QPrintPreviewDialog still open) he wants to print pages 9-10.

When I clear closing_checkbox, I want QPrintPreviewDialog not to close after clicking on Print button. Hot to do that? I tried subclassing QPrintPreviewDialog and implementing accept(), reject(), closeEvent(), but without luck.


Solution

  • One possible solution is to override the accept() method:

    class PrintPreviewDialog(QPrintPreviewDialog):
        def accept(self):
            pass
    
    dialog = PrintPreviewDialog()