pythonpython-3.xpyqtpyqt5qwebview

sudo apt install python3-pyqt5 and other apt install methods


here is the error.

QWebView is not defined

I am following along from a PyQt4 tutorial at https://wiki.python.org/moin/PyQt/Embedding%20Widgets%20in%20Web%20Pages.

I understand defining but what exactly should I define here and where should I define it?

Where would I install QWebView?

I know the link provided is a PyQt4 example and I am using PyQt5. I know there have been changes but I have not found exactly what the answer could be now.

Here is some code:

import sys
from PyQt5.QtCore import QSize, Qt
from PyQt5.QtGui import *
from PyQt5.QtWebKit import *
from PyQt5.QtWidgets import *

html = \
"""<html>
<head>
<title>Python Web Plugin Test</title>
</head>

<body>
<h1>Python Web Plugin Test</h1>
<object type="x-pyqt/widget" width="200" height="200"></object>
<p>This is a Web plugin written in Python.</p>
</body>
</html>
"""

class WebWidget(QWidget):

    def paintEvent(self, event):
        painter = QPainter()
        painter.begin(self)
        painter.setBrush(Qt.white)
        painter.setPen(Qt.black)
        painter.drawRect(self.rect().adjusted(0, 0, -1, -1))
        painter.setBrush(Qt.red)
        painter.setPen(Qt.NoPen)
        painter.drawRect(self.width()/4, self.height()/4,
                         self.width()/2, self.height()/2)
        painter.end()

    def sizeHint(self):
        return QSize(100, 100)

class WebPluginFactory(QWebPluginFactory):

    def __init__(self, parent = None):
        QWebPluginFactory.__init__(self, parent)

    def create(self, mimeType, url, names, values):
        if mimeType == "x-pyqt/widget":
            return WebWidget()

    def plugins(self):
        plugin = QWebPluginFactory.Plugin()
        plugin.name = "PyQt Widget"
        plugin.description = "An example Web plugin written with PyQt."
        mimeType = QWebPluginFactory.MimeType()
        mimeType.name = "x-pyqt/widget"
        mimeType.description = "PyQt widget"
        mimeType.fileExtensions = []
        plugin.mimeTypes = [mimeType]
        print("plugins")
        return [plugin]

if __name__ == "__main__":

    app = QApplication(sys.argv)
    QWebSettings.globalSettings().setAttribute(QWebSettings.PluginsEnabled, True)
    view = QWebView()
    factory = WebPluginFactory()
    view.page().setPluginFactory(factory)
    view.setHtml(html)
    view.show()
    sys.exit(app.exec_())

Solution

  • To use QtWebkit you have to install the package python3-pyqt5.qtwebkit. On the other hand, the main change from Qt4 to Qt5 was the reorganization of the modules, and that happened with QtWebKit that was divided into QtWebKit and QtWebkitWidgets, so QWebView belongs to the last sub-module:

    import sys
    from PyQt5.QtCore import Qt
    from PyQt5.QtGui import QPainter
    from PyQt5.QtWidgets import QApplication, QWidget
    from PyQt5.QtWebKit import QWebPluginFactory, QWebSettings
    from PyQt5.QtWebKitWidgets import QWebView
    
    html = """<html>
    <head>
    <title>Python Web Plugin Test</title>
    </head>
    
    <body>
    <h1>Python Web Plugin Test</h1>
    <object type="x-pyqt/widget" width="200" height="200"></object>
    <p>This is a Web plugin written in Python.</p>
    </body>
    </html>
    """
    
    
    class WebWidget(QWidget):
        def paintEvent(self, event):
            painter = QPainter()
            painter.begin(self)
            painter.setBrush(Qt.white)
            painter.setPen(Qt.black)
            painter.drawRect(self.rect().adjusted(0, 0, -1, -1))
            painter.setBrush(Qt.red)
            painter.setPen(Qt.NoPen)
            painter.drawRect(
                self.width() / 4, self.height() / 4, self.width() / 2, self.height() / 2
            )
            painter.end()
    
        def sizeHint(self):
            return QSize(100, 100)
    
    
    class WebPluginFactory(QWebPluginFactory):
        def __init__(self, parent=None):
            QWebPluginFactory.__init__(self, parent)
    
        def create(self, mimeType, url, names, values):
            if mimeType == "x-pyqt/widget":
                return WebWidget()
    
        def plugins(self):
            plugin = QWebPluginFactory.Plugin()
            plugin.name = "PyQt Widget"
            plugin.description = "An example Web plugin written with PyQt."
            mimeType = QWebPluginFactory.MimeType()
            mimeType.name = "x-pyqt/widget"
            mimeType.description = "PyQt widget"
            mimeType.fileExtensions = []
            plugin.mimeTypes = [mimeType]
            print("plugins")
            return [plugin]
    
    
    if __name__ == "__main__":
    
        app = QApplication(sys.argv)
        QWebSettings.globalSettings().setAttribute(QWebSettings.PluginsEnabled, True)
        view = QWebView()
        factory = WebPluginFactory()
        view.page().setPluginFactory(factory)
        view.setHtml(html)
        view.show()
        sys.exit(app.exec_())
    

    Note: Since Qt 5.6 QtWebkit is no longer officially maintained (there is a fork maintained by the community) as it was replaced by QtWebEngine so to use QtWebkit you must use the official repositories of each distribution or compile it manually. The functionality of the QWebPluginFactory cannot be implemented by QtWebEngine since the rendering is not made by Qt but by chromium.