Question

If I have an open QWebView, I like its default context menu with "Open in New Window" as an option for links. However, I can't seem to find a way to act when the user requests a link be opened in a new window. Overriding the QWebPage.createWindow method doesn't seem to work, because the method is not invoked when the user chooses to open a link in a new window.

Any recommendations? I'm using PyQt.

Example code:

class LocalWebPage(QWebPage):
    def acceptNavigationRequest(self, webFrame, networkRequest, navigationType):
        print '*acceptNavigationRequest**',webFrame, networkRequest, navigationType
        return QWebPage.acceptNavigationRequest(self, webFrame, networkRequest, navigationType)

    def createWindow(self, windowType):
        print '--createWindow', windowType
        return QWebPage.createWindow(self, windowType)


class Browser(Ui_MainWindow, QMainWindow):
    def __init__(self, base, name):

        ...
        self.page = LocalWebPage()
        self.webViewMain = QWebView(self.centralwidget)
        self.webViewMain.setPage(self.page)
        ...

I have the debugging prints in there to verify that createWindow is not being called.

Was it helpful?

Solution

You'll need to call the createWindow method of the QWebView yourself, for example by reimplementing the triggerAction of the QWebPage, something like this:

#!/usr/bin/env python
#-*- coding:utf-8 -*-

from PyQt4 import QtGui, QtCore, QtWebKit

class MyPage(QtWebKit.QWebPage):
    def __init__(self, parent=None):
        super(MyPage, self).__init__(parent)

    def triggerAction(self, action, checked=False):
        if action == QtWebKit.QWebPage.OpenLinkInNewWindow:
            self.createWindow(QtWebKit.QWebPage.WebBrowserWindow)

        return super(MyPage, self).triggerAction(action, checked)


class MyWindow(QtWebKit.QWebView):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)

        self.myPage = MyPage(self)

        self.setPage(self.myPage)

    def createWindow(self, windowType):
        if windowType == QtWebKit.QWebPage.WebBrowserWindow:
            self.webView = MyWindow()
            self.webView.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)

            return self.webView

        return super(MyWindow, self).createWindow(windowType)

if __name__ == "__main__":
    import sys

    app = QtGui.QApplication(sys.argv)
    app.setApplicationName('MyWindow')

    main = MyWindow()
    main.show()
    main.load(QtCore.QUrl("http://www.example.com"))

    sys.exit(app.exec_())

OTHER TIPS

The link that was right-clicked can be found by using hitTestContent in the contextMenuEvent method of the QWebView:

def contextMenuEvent(self, event):
  pos = event.pos()
  element = self.page().mainFrame().hitTestContent(pos)
  link_url = str(element.linkUrl().toString())
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top