2

createWindowPyQt webkit でメソッドを処理しようとしています。これを行うと、PyQt はメソッドに a QWebPage.WebWindowType(またはQWebPage::WebWindowTypec++) を与えます。必要なのは新しいウィンドウを作成するための URL だけなので、このクラスをどうすればよいかわかりません。ドキュメントもそれをあまりよく説明していません: http://doc.qt.digia.com/qt/qwebpage.html#WebWindowType-enum

これを「タブ」クラスと統合しようとしています:

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呼び出しなど)。そして、それは仮想関数であることに注意してください。これは、またはのサブクラスでオーバーライドされた場合、再実装された関数をQt によって内部的に呼び出すことができることを意味します。独自の関数を JavaScript コードから呼び出す必要がある場合、これは明らかに重要です。window.open()createWindowQWebViewQWebPagecreatWindow

したがって、Web ページ上の JavaScript プログラムでブラウザ ウィンドウ クラスのインスタンスを作成して開くことができるようにする場合は、その関数をサブクラス化 QWebViewして再実装しcreateWindowます (上記の例のように)。

この関数は、単純に作成して表示する場合(たとえば、新しいタブを追加するcreateWindow場合) にはまったく必要ありません。QWebViewは、Web ページを表示するためのQWebView単なるコンテナであり、他のウィジェットと同様に作成および表示されます。

于 2012-11-30T21:41:11.423 に答える