2

我正在尝试处理createWindowPyQt webkit 中的方法。当你这样做时,PyQt 会给出方法 a QWebPage.WebWindowType(或QWebPage::WebWindowType在 c++ 中)。我只需要一个 URL 来创建一个新窗口,所以我不确定如何处理这个类。文档也没有很好地解释它:http: //doc.qt.digia.com/qt/qwebpage.html#WebWindowType-enum

我正在尝试将其与我的“Tab”类集成:

class Tab(QtGui.QWidget):
    """
    Contains the variables and methods needed to open the Qt
    based user interface and the event bus to allow interaction.
    """
    def __init__(self, url, window):
        """
        Set the up the following:
          1) Initialise the Qt user interface.
          2) Set margins.
          3) Initialise the cookie jar.
          4) Set the default URL.
          5) Set the history buttons to disabled (there is not history yet).
          5) Hide the tools menu.
          6) Create the GUI event bus.
          7) Set keyboard bindings.
        """
        self.window = window
        QtGui.QWidget.__init__(self)
        self.ui = Ui_Browser()
        self.ui.setupUi(self)

        l = self.layout()
        l.setMargin(0)
        self.ui.horizontalLayout.setMargin(0)

        try:
            self.ui.webView.page().networkAccessManager().setCookieJar(self.window.cookies)
        except:
            pass

        self.ui.webView.setUrl(url)
        self.ui.url.setText(url.toString())

        self.ui.back.setEnabled(False)
        self.ui.forward.setEnabled(False)

        self.ui.toolsBox.hide()
        self.ui.tools.setChecked(False)

        QtCore.QObject.connect(self.ui.back, QtCore.SIGNAL("clicked()"), self.back)
        QtCore.QObject.connect(self.ui.forward, QtCore.SIGNAL("clicked()"), self.forward)
        QtCore.QObject.connect(self.ui.refresh, QtCore.SIGNAL("clicked()"), self.refresh)
        QtCore.QObject.connect(self.ui.url, QtCore.SIGNAL("returnPressed()"), self.url)
        QtCore.QObject.connect(self.ui.webView, QtCore.SIGNAL("linkClicked (const QUrl&)"), self.navigate)
        QtCore.QObject.connect(self.ui.webView, QtCore.SIGNAL("urlChanged (const QUrl&)"), self.navigate)
        QtCore.QObject.connect(self.ui.webView, QtCore.SIGNAL("titleChanged(const QString&)"), self.title)
        QtCore.QObject.connect(self.ui.webView, QtCore.SIGNAL("loadStarted()"), self.showProgressBar)
        QtCore.QObject.connect(self.ui.webView, QtCore.SIGNAL("loadProgress(int)"), self.setProgressBar)
        QtCore.QObject.connect(self.ui.webView, QtCore.SIGNAL("loadFinished(bool)"), self.hideProgressBar)
        QtCore.QObject.connect(self.ui.toolPrint, QtCore.SIGNAL("clicked()"), self.printPage)
        self.ui.webView.createWindow = self.createWindow

        QtGui.QShortcut(QtGui.QKeySequence("Backspace"), self, self.back)
        QtGui.QShortcut(QtGui.QKeySequence("F5"), self, self.refresh)
        QtGui.QShortcut(QtGui.QKeySequence("Ctrl+p"), self, self.printPage)

    def url(self):
        """
        Go to URL entered.
        """
        self.setHistory()
        url = self.ui.url.text()
        if not str(url).startswith("http://"):
            url = "http://" + url
        self.ui.webView.setUrl(QtCore.QUrl(url))

    def navigate(self, url):
        """
        Navigate to page requested.
        """
        self.setHistory()
        self.ui.url.setText(url.toString())

    def refresh(self):
        """
        Refresh the page.
        """
        self.ui.webView.setUrl(QtCore.QUrl(self.ui.webView.url()))

    def back(self):
        """
        Enable the back button.
        """
        page = self.ui.webView.page()
        history = page.history()
        history.back()
        if history.canGoBack():
            self.ui.back.setEnabled(True)
        else:
            self.ui.back.setEnabled(False)

    def forward(self):
        """
        Enable the forward button.
        """
        page = self.ui.webView.page()
        history = page.history()
        history.forward()
        if history.canGoForward():
            self.ui.forward.setEnabled(True)
        else:
            self.ui.forward.setEnabled(False)

    def title(self, title):
        """
        Change the title of the window.
        """
        self.window.tabs.setTabText(self.window.tabs.indexOf(self), title) or (self.window.setWindowTitle(title) if self.isThisFocused() else "New Tab")

    def createWindow(self, WebWindowType):
        """
        Overide the default behaviour.
        """
        tab = Tab(QtCore.QUrl("about:blank"), self.window)
        print(mode)
        if mode == QtWebKit.QWebPage.WebModalDialog:
            tab.ui.webView.setWindowModality(QtCore.Qt.ApplicationModal)
        self.window.tabs.setCurrentIndex(self.window.tabs.addTab(tab, ""))

    def isThisFocused(self):
        """
        Return whether this tab is focused or not.
        """
        if self.window.tabs.currentWidget() == self:
            return True
        return False

    def setHistory(self):
        """
        Check history and update buttons.
        """
        page = self.ui.webView.page()
        history = page.history()
        if history.canGoBack():
            self.ui.back.setEnabled(True)
        else:
            self.ui.back.setEnabled(False)
        if history.canGoForward():
            self.ui.forward.setEnabled(True)
        else:
            self.ui.forward.setEnabled(False)

    def showProgressBar(self):
        """
        We're loading a page, show the load progress bar.
        """
        self.ui.progress.show()

    def setProgressBar(self, percent):
        """
        Set the percentage of the progress bar.
        """
        self.ui.progress.setValue(percent)

    def hideProgressBar(self, bool):
        """
        We've finished loading the page, there is no need for the progress bar.
        """
        self.ui.progress.hide()

    def printPage(self):
        """
        Use Qt's goodness to print the page.
        """
        previewer = QtGui.QPrintPreviewDialog(paintRequested=self.ui.webView.print_)
        previewer.exec_()
4

1 回答 1

0

createWindow函数用于处理打开新窗口的请求(例如,javascript调用window.open())。

默认情况下,createWindow什么都不做,因此必须在子类中重新实现它。

此外,要使用 javascript,必须在web 设置中指定允许javascript 程序打开新窗口。

这是一个演示脚本,说明了如何使用createWindow

from PyQt4 import QtGui, QtCore, QtWebKit

class Browser(QtWebKit.QWebView):
    _windows = set()

    @classmethod
    def _removeWindow(cls, window):
        if window in cls._windows:
            cls._windows.remove(window)

    @classmethod
    def newWindow(cls):
        window = cls()
        cls._windows.add(window)
        return window

    def __init__(self, parent=None):
        QtWebKit.QWebView.__init__(self, parent)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)
        self.settings().setAttribute(
            QtWebKit.QWebSettings.JavascriptEnabled, True)
        self.settings().setAttribute(
            QtWebKit.QWebSettings.JavascriptCanOpenWindows, True)

    def closeEvent(self, event):
        self._removeWindow(self)
        event.accept()

    def createWindow(self, mode):
        window = self.newWindow()
        if mode == QtWebKit.QWebPage.WebModalDialog:
            window.setWindowModality(QtCore.Qt.ApplicationModal)
        window.show()
        return window

html = """
<html>
<head>
<title>Test Page</title>
<script type="text/javascript"><!--
var url = 'https://www.google.com'
var count = 0
function newWindow() {
    count += 1;
    window.open(url, 'testwindow' + count, 'width=640,height=480');
}
--></script>
</head>
<body>
<input type="button" value="New Window" onclick="newWindow()" />
<p><a href="https://www.google.com">Test Link</a></p>
</body>
</html>"""

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    browser = Browser()
    browser.setHtml(html)
    browser.show()
    sys.exit(app.exec_())

注意:必须保留对任何新创建的窗口的引用;不这样做几乎肯定会导致分段错误)。

编辑

只是为了澄清:

createWindow函数旨在处理打开新浏览器窗口的外部请求(例如,如上例所示的 javascript调用)。请注意,这是一个函数。这意味着如果它在or的子类中被重写,则重新实现的函数可以由 Qt在内部调用。如果您需要从 javascript 代码调用自己的函数,这显然至关重要。window.open()createWindowQWebViewQWebPagecreatWindow

因此,如果您希望网页上的 javascript 程序能够创建和打开浏览器窗口类的实例,则子类 QWebView化并重新实现其createWindow功能(如上例所示)。

简单地创建和显示一个(例如添加一个新选项卡)createWindow根本不需要该功能。QWebViewAQWebView只是一个用于显示网页的容器,它的创建和显示就像任何其他小部件一样。

于 2012-11-30T21:41:11.423 回答