Python使用PYQT5中的PrinterDialog将PIL图像发送到打印机-问题PYQT5窗口关闭

Python使用PYQT5中的PrinterDialog将PIL图像发送到打印机-问题PYQT5窗口关闭,python,scipy,pyqt5,python-imaging-library,Python,Scipy,Pyqt5,Python Imaging Library,我正在尝试从我的PYQt5使用打印按钮(self.printbn.clicked.connect(self.do_printout)…)发送PIL图像 问题是,如果我按“取消”和“打印”,主窗口将关闭。使用app.exec()关闭子例程也未成功。 (Python 3.7、PyQT5和Windows操作系统) 我尝试了不同的方法-使用win32print、win32ui、win32gui可能是一种替代方法:如果您有这样打印PIL图像的知识,请告诉我。蒂姆·戈尔登也不为我工作()。 我不想使用其他g

我正在尝试从我的PYQt5使用打印按钮(self.printbn.clicked.connect(self.do_printout)…)发送PIL图像

问题是,如果我按“取消”和“打印”,主窗口将关闭。使用app.exec()关闭子例程也未成功。 (Python 3.7、PyQT5和Windows操作系统)

我尝试了不同的方法-使用win32print、win32ui、win32gui可能是一种替代方法:如果您有这样打印PIL图像的知识,请告诉我。蒂姆·戈尔登也不为我工作()。 我不想使用其他gui软件包只是为了打印。 重要的是能够使用PrinterDialog选择打印机。 谢谢你的帮助

以下是更完整的设置:

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel,  QPushButton
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5 import QtGui, QtWidgets, QtPrintSupport, QtCore
from PIL import Image
from PIL.ImageQt import ImageQt

class App(QWidget):

    def __init__(self, im):
        super().__init__()
        self.title = 'PyQt5 image'
        self.left = 100
        self.top = 100
        self.width = 640
        self.height = 480
        self.im = im

        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        label = QLabel(self)

        qim = ImageQt(self.im).copy()
        self.im = QtGui.QPixmap.fromImage(qim)

        print(type(self.im))
        label.setPixmap(self.im)
        self.resize(self.im.width(), self.im.height())

        cb = QPushButton('Print', self)
        cb.move(self.width, self.height +200)
        cb.setGeometry(QtCore.QRect(0, 550, 799, 40))
        cb.clicked.connect(self.show_cat)
        self.show()

    def show_cat(self):
        printer = QtPrintSupport.QPrinter()
        dialog = QtPrintSupport.QPrintDialog(printer)

        if dialog.exec_() == QtWidgets.QDialog.Accepted:
            self.handle_paint_request(printer)

    def handle_paint_request(self, printer):
        printer.setOrientation(QtPrintSupport.QPrinter.Landscape)
        printer.setPaperSize(QtPrintSupport.QPrinter.A4)
        printer.setPageSize(QtPrintSupport.QPrinter.A4)
        printer.setPageMargins(0, 0, 0, 0, QtPrintSupport.QPrinter.Millimeter)

        # Create painter
        painter = QtGui.QPainter(printer)        # Start painter
        painter.drawPixmap(10, 10, self.im)
        painter.end()

class Ui_MainWindow(object):

    def setupUi(self, MainWindow):
        MainWindow.resize(506, 312)
        self.centralwidget = QtWidgets.QWidget(MainWindow)

        # adding pushbutton
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setText("Print")
        self.pushButton.setGeometry(QtCore.QRect(200, 150, 93, 28))

        # adding signal and slot
        self.pushButton.clicked.connect(self.do_print)

        MainWindow.setCentralWidget(self.centralwidget)
        #self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def do_print(self):
        app = QApplication(sys.argv)
        im = Image.open("shot.png").convert("RGB")
        ex = App(im)

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)

    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())


您必须在QPrint对话框中设置QPrinter,并且
painter=QtGui.QPainter(print)
painter=QtGui.QPainter()painter.begin(printer)
是等效的,因此您应该只使用其中一个选项

import sys

from PyQt5 import QtCore, QtGui, QtWidgets, QtPrintSupport

from PIL import Image
from PIL.ImageQt import ImageQt


class App:
    def __init__(self, im):
        printer = QtPrintSupport.QPrinter()
        dialog = QtPrintSupport.QPrintDialog(printer)
        if dialog.exec_() == QtWidgets.QDialog.Accepted:
            self.handle_paint_request(printer, im)

    def handle_paint_request(self, printer, im):
        printer.setOrientation(QtPrintSupport.QPrinter.Landscape)
        printer.setPaperSize(QtPrintSupport.QPrinter.A4)
        printer.setPageSize(QtPrintSupport.QPrinter.A4)
        printer.setPageMargins(0, 0, 0, 0, QtPrintSupport.QPrinter.Millimeter)

        im = ImageQt(im).copy()

        painter = QtGui.QPainter(printer)
        image = QtGui.QPixmap.fromImage(im)
        painter.drawPixmap(10, 10, image)
        painter.end()


def do_print(im):
    app = QtWidgets.QApplication(sys.argv)
    gui = App(im)


if __name__ == "__main__":
    im = Image.open("shot.png").convert("RGB")
    do_print(im)

谢谢我仍然很难进入我的班级。因此,我添加了一个设置,同时使用一个主窗口来启动printing类。问题是,它只在我分步运行时才起作用-当我执行代码时,屏幕会很快闪烁并退出。@Erich您的问题与初始代码不同,因此这次我将添加解决方案,但下次您将不得不问一个新问题。不幸的是,我们不会在每次项目失败时都回答相同的问题。
import sys

from PyQt5 import QtCore, QtGui, QtWidgets, QtPrintSupport

from PIL import Image
from PIL.ImageQt import ImageQt


class App:
    def __init__(self, im):
        printer = QtPrintSupport.QPrinter()
        dialog = QtPrintSupport.QPrintDialog(printer)
        if dialog.exec_() == QtWidgets.QDialog.Accepted:
            self.handle_paint_request(printer, im)

    def handle_paint_request(self, printer, im):
        printer.setOrientation(QtPrintSupport.QPrinter.Landscape)
        printer.setPaperSize(QtPrintSupport.QPrinter.A4)
        printer.setPageSize(QtPrintSupport.QPrinter.A4)
        printer.setPageMargins(0, 0, 0, 0, QtPrintSupport.QPrinter.Millimeter)

        im = ImageQt(im).copy()

        painter = QtGui.QPainter(printer)
        image = QtGui.QPixmap.fromImage(im)
        painter.drawPixmap(10, 10, image)
        painter.end()


def do_print(im):
    app = QtWidgets.QApplication(sys.argv)
    gui = App(im)


if __name__ == "__main__":
    im = Image.open("shot.png").convert("RGB")
    do_print(im)