PDF with QWebView: missing refresh/repaint after l

2019-02-20 01:59发布

问题:

I use the QWebView (python 3.3 + pyside 1.1.2 + Qt 4.8) as FileViewer. Picture, Text, HTML, ... all fine, but PDF has a display problem. I tested two possible ways.

  1. internal pdf viewer: after use webview.load(file) it loads, but the screen is blank, after loading another file, all works fine, it shows the file
  2. pdf.js: after use setContent() with filebase, it loads the webviewer.html/.js with a white page and the loading circle. The screen only refresh if I resize the form or use the scrollbars, but then all is fine

I don't find an event for "plugin/javascript finished loading", so I could force a repaint or so. Here an example code for case 1:

import sys
from PySide import QtCore, QtGui, QtWebKit #@UnusedWildImport

class DialogTest(QtGui.QDialog):
    def __init__(self, parent = None):
        super(DialogTest, self).__init__(parent)
        self.resize(620, 600)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

        self.PreviewBox = QtWebKit.QWebView()   
        self.PreviewBox.settings().setAttribute(QtWebKit.QWebSettings.PluginsEnabled, True)
        self.PreviewBox.settings().setAttribute(QtWebKit.QWebSettings.WebAttribute.DeveloperExtrasEnabled, True)
        self.PreviewBox.settings().setAttribute(QtWebKit.QWebSettings.PrivateBrowsingEnabled, True)
        self.PreviewBox.settings().setAttribute(QtWebKit.QWebSettings.LocalContentCanAccessRemoteUrls, True)
        self.PreviewBox.loadFinished.connect(self._loadfinished)
        self.button_test1 = QtGui.QPushButton("File 1")
        self.button_test1.clicked.connect(self._onselect1)
        self.button_test2 = QtGui.QPushButton("File 2")
        self.button_test2.clicked.connect(self._onselect2)
        layout_Buttons = QtGui.QHBoxLayout()        
        layout_Buttons.addWidget(self.button_test1)        
        #layout_Buttons.addStretch()
        layout_Buttons.addWidget(self.button_test2) 
        layout_Main = QtGui.QVBoxLayout()      
        layout_Main.addLayout(layout_Buttons)  
        layout_Main.addWidget(self.PreviewBox)                  
        self.setLayout(layout_Main)      
    def Execute(self):
        self.show()
        self.exec_()
    def _onselect1(self):
        self.PreviewBox.load(QtCore.QUrl().fromLocalFile("c:\\tmp\\test1.pdf"))
    def _onselect2(self):
        self.PreviewBox.load(QtCore.QUrl().fromLocalFile("c:\\tmp\\test2.pdf"))
    def _loadfinished(self, ok):
        #self.PreviewBox.repaint()
        pass
app = QtGui.QApplication(sys.argv)
DialogTest().Execute() 

Edit: Workaround Case 1 (webkit plugin) has an otherbug, it takes the focus to itself, so this solution isn't acceptable to me. I played with the pdf.js again and found a workaroud:

    self.PreviewBox.setHtml(content, baseUrl = QtCore.QUrl().fromLocalFile(path))
    self.PreviewBox.hide()
    QtCore.QTimer.singleShot(700, self.PreviewBox.show)

The hide() must be after the content filling and the timer haven't to be too low.

//jay

回答1:

I just solved a similar problem cleaning the QWebView before every pdf load. Be careful with the loadFinished() signal.

In your example:

self.PreviewBox.load(QUrl('about:blank'))

or, in case we don't like 'about:blank' this may be a more portable solution:

self.PreviewBox.setHtml('<html><head></head><title></title><body></body></html>')