pythonraspberry-pipyqt5qwebkit

Print error Pyqt Qwebkit on raspbian/ linux


Traceback (most recent call last):
  File "pos.py", line 57, in printDocument
    self.page.print(printer, printPreview)
    AttributeError: 'QWebPage' object has no attribute 'print'
    Aborted

I am using raspbian os. and am trying to print from QWebkit using QWebPage I will share the code block below. Please share ur thoughts on how to over come this error.

class PrintHandler(QObject):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.m_page = None
        self.m_inPrintPreview = False

    @property
    def page(self):
        return self.m_page

    @page.setter
    def page(self, page):
        if isinstance(page, QWebPage):
            self.m_page = page
            self.page.printRequested.connect(self.printPreview)
        else:
            raise TypeError("page must be a QWebEnginePage")

    @pyqtSlot()
    def print(self):
        printer = QPrinter()
        dialog = QPrintDialog(printer, self.page.view())
        if dialog.exec_() != QDialog.Accepted:
            return
        self.printDocument(printer)

    @pyqtSlot()
    def printPreview(self):
        if self.page is None:
            return
        if self.m_inPrintPreview:
            return
        self.m_inPrintPreview = True
        printer = QPrinter()
        preview = QPrintPreviewDialog(printer, self.page.view())
        preview.paintRequested.connect(self.printDocument)
        preview.exec_()
        self.m_inPrintPreview = False

    @pyqtSlot(QPrinter)
    def printDocument(self, printer):
        result = False
        loop = QEventLoop()

        def printPreview(sucess):
            nonlocal result
            result = sucess
            loop.quit()
        self.page.print(printer, printPreview)
        loop.exec_()
        if not result:
            painter = QPainter()
            if painter.begin(printer):
                font = painter.font()
                font.setPixelSize(20)
                painter.setFont(font)
                painter.drawText(QPointF(10, 25), "Could not generate print preview.")
                painter.end()


class Mainwindow(QMainWindow):
    def __init__(self,*args,**kwargs):
        super(Mainwindow,self).__init__(*args,**kwargs)
    
        self.web = QWebView()
        self.web.loadProgress.connect(self.print_percent)
        self.web.loadFinished.connect(self.print_load_finished)
        url="https://www.google.com"
        self.web.load(QUrl(url))
        
        self.setCentralWidget(self.web)
        
        menu = QToolBar("Toolbar")
        self.addToolBar(menu)
        menu.setIconSize(QSize(40,40))
        
        Print = QAction(QIcon(os.path.join('icons','print.png')),"Print",self)
        Print.setStatusTip("Refresh the page")
        menu.addAction(Print)
        handler = PrintHandler(self)
        handler.page = self.web.page()
        Print.triggered.connect(handler.printPreview)

The code was working with QWebEngine view in windows since i could not find how to accommodate QWebEngine in raspbian i migrated to QWebKit. almost everything worked fine.

But I am getting error on print.


Solution

  • QtWebEngine is not compatible with QtWebkit so do not expect that the analog components have the same methods, also if you want to port one technology to another it is recommended to use the docs of both technologies and thus avoid blind translations.

    Considering the above, and if the docs are revised, it is observed that the QWebPage of QtWebkit does not have the "print" method, so you will have to use QWebView.

    Another difference is that the print in QtWebkit is synchronous unlike QtWebEngine is asynchronous so the QEventLoop is not necessary.

    class PrintHandler(QObject):
        def __init__(self, parent=None):
            super().__init__(parent)
            self.m_page = None
            self.m_inPrintPreview = False
    
        @property
        def page(self):
            return self.m_page
    
        @page.setter
        def page(self, page):
            if isinstance(page, QWebPage):
                self.m_page = page
                self.page.printRequested.connect(self.printPreview)
            else:
                raise TypeError("page must be a QWebEnginePage")
    
        @pyqtSlot()
        def print(self):
            printer = QPrinter()
            dialog = QPrintDialog(printer, self.page.view())
            if dialog.exec_() != QDialog.Accepted:
                return
            self.printDocument(printer)
    
        @pyqtSlot()
        def printPreview(self):
            if self.page is None:
                return
            if self.m_inPrintPreview:
                return
            self.m_inPrintPreview = True
            printer = QPrinter()
            preview = QPrintPreviewDialog(printer, self.page.view())
            preview.paintRequested.connect(self.printDocument)
            preview.exec_()
            self.m_inPrintPreview = False
    
        @pyqtSlot(QPrinter)
        def printDocument(self, printer):
            self.page.view().print_(printer)