qt 디자이너 사용해서 프린터와 pdf 저장하기 작성중입니다. 출력시 에러가 발생됩니다.메인 윈도우 창 전체를 프린터 및 pdf로 저장하고 싶습니다.

조회수 269회
from PyQt5.QtGui import *
from PyQt5 import uic
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5 import QtWidgets, uic
from PyQt5.QtWidgets import QApplication, QWidget, QTableWidget, QTableWidgetItem, QVBoxLayout, QPushButton, QDialog
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPdfWriter, QPagedPaintDevice, QPainter, QScreen, QPixmap
from PyQt5.QtPrintSupport import QPrinter, QPrintDialog
import sys
import random


QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)
form_class = uic.loadUiType("qt semple7.ui")[0]

class WindowClass(QMainWindow, form_class) :

    def __init__(self) :
        super().__init__()
        self.setupUi(self)

        self.pushButton_3.clicked.connect(self.btnClick)
        self.pushButton_5.clicked.connect(self.btnClick2)


    def btnClick(self):
        # 프린터 생성, 실행
        printer = QPrinter()
        dlg = QPrintDialog(printer, self)
        if dlg.exec() == QDialog.Accepted:
            # Painter 생성
            qp = QPainter()
            qp.begin(printer)        

            # 여백 비율
            wgap = printer.pageRect().width()*0.1
            hgap = printer.pageRect().height()*0.1

            # 화면 중앙에 위젯 배치
            xscale = (printer.pageRect().width()-wgap)/self.table.width()
            yscale = (printer.pageRect().height()-hgap)/self.table.height()
            scale = xscale if xscale < yscale else yscale        
            qp.translate(printer.paperRect().x() + printer.pageRect().width()/2, printer.paperRect().y() + printer.pageRect().height()/2)
            qp.scale(scale, scale);
            qp.translate(-self.table.width()/2, -self.table.height()/2);        

            # 인쇄
            self.table.render(qp)

            qp.end()  

    def btnClick2(self):
        # pdf 생성
        pdf = QPdfWriter('test.pdf')
        pdf.setPageSize(QPagedPaintDevice.A4)

        # 화면 캡쳐        
        screen = QApplication.primaryScreen()
        img = screen.grabWindow(self.winId(), 0,0, self.rect().width(),self.rect().height())

        # 3항 연산자 (a if test else b, 만약 test가 참이면 a, 아니면 b)
        # 이미지 크기는 큰 값 기준, PDF 크기는 작은값 기준(화면 초과 방지)
        img_size = img.width() if img.width()-img.height() > 0 else img.height()
        pdf_size = pdf.width() if pdf.width()-pdf.height() < 0 else pdf.height()

        # 최적 비율 얻기
        ratio = pdf_size / img_size

        # pdf에 쓰기
        qp = QPainter()
        qp.begin(pdf)
        point = QPoint(0, 0)
        qp.drawPixmap(point, img.width()*ratio, img.height()*ratio, img)
        qp.end()


if __name__ == "__main__" :
    app = QApplication(sys.argv)
    myWindow = WindowClass()
    myWindow.show()
    app.exec_()

1 답변

  • 안녕하세요! 코드를 살펴보니 self.table 이라는 변수를 찾을 수 없습니다. 프린터를 이용해서 출력하고자 하는 위젯을 self.table로 변경해보시겠어요? 이 부분을 찾아서 프린트하면 에러가 발생하지 않을 것입니다.

    또한, PDF 출력 부분에서 QPainter가 PDF 파일을 출력하기 전에 pdf.begin() 메서드를 호출해야 합니다. qp.begin(pdf)로 변경해보세요. 그리고 PDF 파일 생성을 완료한 후 qp.end()를 호출하여 마무리를 해주세요.

    아래는 수정된 코드입니다.

    from PyQt5.QtGui import *
    from PyQt5 import uic
    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    from PyQt5 import QtWidgets, uic
    from PyQt5.QtWidgets import QApplication, QWidget, QTableWidget, QTableWidgetItem, QVBoxLayout, QPushButton, QDialog
    from PyQt5.QtCore import Qt
    from PyQt5.QtGui import QPdfWriter, QPagedPaintDevice, QPainter, QScreen, QPixmap
    from PyQt5.QtPrintSupport import QPrinter, QPrintDialog
    import sys
    import random
    
    
    QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)
    form_class = uic.loadUiType("qt semple7.ui")[0]
    
    class WindowClass(QMainWindow, form_class) :
    
        def __init__(self) :
            super().__init__()
            self.setupUi(self)
    
            self.pushButton_3.clicked.connect(self.btnClick)
            self.pushButton_5.clicked.connect(self.btnClick2)
    
    
        def btnClick(self):
            # 프린터 생성, 실행
            printer = QPrinter()
            dlg = QPrintDialog(printer, self)
            if dlg.exec() == QDialog.Accepted:
                # Painter 생성
                qp = QPainter()
                qp.begin(printer)
    
                # 여백 비율
                wgap = printer.pageRect().width()*0.1
                hgap = printer.pageRect().height()*0.1
    
                # 화면 중앙에 위젯 배치
                xscale = (printer.pageRect().width()-wgap)/self.centralWidget().width()
                yscale = (printer.pageRect().height()-hgap)/self.centralWidget().height()
                scale = xscale if xscale < yscale else yscale
                qp.translate(printer.paperRect().x() + printer.pageRect().width()/2, printer.paperRect().y() + printer.pageRect().height()/2)
                qp.scale(scale, scale);
                qp.translate(-self.centralWidget().width()/2, -self.centralWidget().height()/2);
    
                # 인쇄
                self.centralWidget().render(qp)
    
                qp.end()
    
        def btnClick2(self):
            # pdf 생성
            pdf = QPdfWriter('test.pdf')
            pdf.setPageSize(QPagedPaintDevice.A4)
    
            # Painter 생성
            qp = QPainter()
            qp.begin(pdf)
    
            # 화면 캡쳐
            screen = QApplication.primaryScreen()
            img = screen.grabWindow(self.winId(), 0, 0, self.rect().width(), self.rect().height())
    
            # 3항 연산자 (a if test else b, 만약 test가 참이면 a, 아니면 b)
            # 이미지 크기는 큰 값 기준, PDF 크기는 작은값
    
    

    `

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)