我正在尝试处理PyQt webkit中的createWindow
方法。执行此操作时,PyQt为方法提供QWebPage.WebWindowType
(或c ++中的QWebPage::WebWindowType
)。我只需要一个创建新窗口的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_()
答案 0 :(得分:0)
createWindow函数用于处理打开新窗口的请求(例如javascript window.open()
调用)。
默认情况下,createWindow
不执行任何操作,因此必须在子类中重新实现它。
此外,要使用javascript,web-settings必须指定javascript程序为allowed to open new windows。
这是一个演示脚本,演示了如何使用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_())
( NB :必须将引用保留到任何新创建的窗口;否则几乎肯定会导致分段错误。
修改强>:
只是为了澄清:
createWindow
函数旨在处理外部请求以打开新的浏览器窗口(例如javascript window.open()
调用,如上面的例子)。请注意createWindow
是虚拟功能。这意味着如果它在QWebView
或QWebPage
的子类中被覆盖,则重新实现的函数可以由Qt在内部调用 。如果您需要从javascript代码调用自己的creatWindow
函数,这显然至关重要。
因此,如果您希望网页上的javascript程序能够创建和打开浏览器窗口类的实例,那么子类 QWebView
并重新实现其createWindow
功能(如上例所示)。
完全不需要createWindow
功能来创建和显示QWebView
(例如添加新标签页)。 QWebView
只是一个用于显示网页的容器,并且像任何其他小部件一样被创建和显示。