Search code examples
pythonpyside2qwebengineview

QWebEngineView - how to open links in system browser


I have the following code snippet working in PySide and need to translate it to work in PySide2. The purpose is to force all links to open in the system browser when clicked (rather than the widget trying to load them):

from PySide.QtWebKit import QWebView, QWebPage

class HtmlView(QWebView):

    def __init__(self, parent=None):
        super(HtmlView, self).__init__(parent)
        self.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks) # not working in PySide2
        self.linkClicked.connect(self.openWebsite) # not working in PySide2

This was my attempt of a translation:

from PySide2.QtWebEngineWidgets import QWebEngineView, QWebEnginePage

class HtmlView(QWebEngineView):

    def __init__(self, parent=None):
        super(HtmlView, self).__init__(parent)
        self.page().setLinkDelegationPolicy(QWebEnginePage.DelegateAllLinks) # not working in PySide2
        self.linkClicked.connect(self.openWebsite) # not working in PySide2

However, QWebEngineView.linkClicked does not exist and neither does QWebEngineView.setLinkDelegationPolicy or QWebEnginePage.DelegateAllLinks.

What is the best way to achieve this in PySide2 without the above?

Edit: I checked the QEvents that are triggered but no event seems to be fired off when a link is clicked, so without the linkClicked event from PySide/Qt4.8 I have no idea how to hook into this.

Thanks, frank


Solution

  • You have to use acceptNavigationRequest:

    This function is called upon receiving a request to navigate to the specified url by means of the specified navigation type type. isMainFrame indicates whether the request corresponds to the main frame or a child frame. If the function returns true, the navigation request is accepted and url is loaded. The default implementation accepts all navigation requests.

    In your case you must reject and open the url when the type is QWebEnginePage::NavigationTypeLinkClicked.

    from PySide2.QtCore import QUrl
    from PySide2.QtGui import QDesktopServices
    from PySide2.QtWidgets import QApplication
    from PySide2.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
    
    
    class WebEnginePage(QWebEnginePage):
        def acceptNavigationRequest(self, url,  _type, isMainFrame):
            if _type == QWebEnginePage.NavigationTypeLinkClicked:
                QDesktopServices.openUrl(url);
                return False
            return True
    
    class HtmlView(QWebEngineView):
        def __init__(self, *args, **kwargs):
            QWebEngineView.__init__(self, *args, **kwargs)
            self.setPage(WebEnginePage(self))
    
    if __name__ == '__main__':
        import sys
    
        app = QApplication(sys.argv)
        w = HtmlView()
        w.load(QUrl("https://stackoverflow.com/questions/47736408/pyside2-qwebview-how-to-open-links-in-system-browser"));
        w.show()
        sys.exit(app.exec_())