Вопрос

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.

Это было полезно?

Решение

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_())

Другие советы

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())
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top