1

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

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Frank Rueter
  • 729
  • 1
  • 10
  • 21

1 Answers1

1

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_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • brilliant, I just stumbled across the same info in another post in here. One thing I forgot: I need links to open in context of a given url (to make relative links work as well as absolute ones). I assume this is the main frame vs sub frame part? Looking into it now... – Frank Rueter Dec 10 '17 at 06:56
  • @FrankRueter That's another question, create another post. If my answer helps you, do not forget to mark it as correct. – eyllanesc Dec 10 '17 at 07:01
  • @FrankRueter In SO you create a post by question, I will help you in the other question when you create the post :P – eyllanesc Dec 10 '17 at 07:02
  • sure, fair enough. Just tested everything and this is most definitely the right answer, thanks! – Frank Rueter Dec 10 '17 at 07:39