我需要能夠對QWebPage中的焦點變化做出反應。我用microFocusChanged()信號,它給了我幾乎所需的行爲,但無論如何,我不知道如何知道哪個元素被選中。我想在頁面上的任何可編輯元素獲取或失去焦點時執行一些操作。如何在QWebView/QWebPage中獲取焦點元素?
預先感謝您
我需要能夠對QWebPage中的焦點變化做出反應。我用microFocusChanged()信號,它給了我幾乎所需的行爲,但無論如何,我不知道如何知道哪個元素被選中。我想在頁面上的任何可編輯元素獲取或失去焦點時執行一些操作。如何在QWebView/QWebPage中獲取焦點元素?
預先感謝您
要你做下面的一個頁面內處理任何HTML事件:
JavaScript添加焦點更改處理程序應該遍歷所有文本元素並添加onfocus和onblur處理程序。更好的做法是將單個處理程序添加到documentElement並使用事件冒泡。不幸的是,onblur廣告不會泡泡。幸運的是,它們有一個叫做DOMFocusIn和DOMFocusOut的冒泡對應物。
下面是一個完整的檢查頁面文本元素捕捉焦點輸入/輸出事件的示例。它在要從JavaScript調用的主窗口上聲明瞭兩個插槽handleFocusIn
和handleFocusOut
,並將主窗口註冊爲名爲MainWindow
的全局JavaScript變量。然後運行JavaScript以將DOMFocusIn/DOMFocusOut事件綁定到這些插槽(間接地,因爲我們需要過濾掉非文本元素)。
import sip
sip.setapi("QString", 2)
sip.setapi("QVariant", 2)
from PyQt4 import QtCore, QtGui, QtWebKit
class MyDialog(QtGui.QMainWindow):
def __init__(self):
super(MyDialog, self).__init__()
self.setWindowTitle("QWebView JavaScript Events")
web_view = QtWebKit.QWebView(self)
web_view.setHtml("""
<html>
<body>
<input type="text" name="text1"/><br/>
<input type="text" name="text2"/><br/>
<input type="submit" value="OK"/>
</body>
</html>""")
self.setCentralWidget(web_view)
main_frame = web_view.page().mainFrame()
main_frame.addToJavaScriptWindowObject("MainWindow", self)
doc_element = main_frame.documentElement()
doc_element.evaluateJavaScript("""
function isTextElement(el) {
return el.tagName == "INPUT" && el.type == "text";
}
this.addEventListener("DOMFocusIn", function(e) {
if (isTextElement(e.target)) {
MainWindow.handleFocusIn(e.target.name);
}
}, false);
this.addEventListener("DOMFocusOut", function(e) {
if (isTextElement(e.target)) {
MainWindow.handleFocusOut(e.target.name);
}
}, false)
""")
self.resize(300, 150)
@QtCore.pyqtSlot(QtCore.QVariant)
def handleFocusIn(self, element_name):
QtGui.QMessageBox.information(
self, "HTML Event", "Focus In: " + element_name)
@QtCore.pyqtSlot(QtCore.QVariant)
def handleFocusOut(self, element_name):
QtGui.QMessageBox.information(
self, "HTML Event", "Focus Out: " + element_name)
app = QtGui.QApplication([])
dialog = MyDialog()
dialog.show()
app.exec_()
(如果你真的找不出Python,我可能會用C++重寫)。
我有同樣的問題,但不想使用JavaScript,因爲我希望它能夠在QWebSettings
禁用JavaScript的情況下也能正常工作。我基本上能想到的兩種方法:
聆聽microFocusChanged
信號的建議,然後做這樣的事情:
frame = page.currentFrame()
elem = frame.findFirstElement('input:not([type=hidden]):focus textarea:focus')
if not elem.isNull():
logging.debug("Clicked editable element!")
這當然有一定的開銷,因爲microFocusChanged
發出多次,並且在很多情況下,不僅僅是如果選擇了輸入字段(例如當選擇文本時)。
在loadFinished
中這樣做可能也是有意義的,因爲元素可以自動聚焦。
我還沒有測試過,但打算很快實施它。
如果我們只關心鼠標點擊,延長mousePressEvent
並做了hitTestContent
有:
def mousePressEvent(self, e):
pos = e.pos()
frame = self.page().frameAt(pos)
pos -= frame.geometry().topLeft()
hitresult = frame.hitTestContent(pos)
if hitresult.isContentEditable():
logging.debug("Clicked editable element!")
return super().mousePressEvent(e)
感謝名單了很多,我認爲應該是這樣的,但我確實沒有足夠的信息。thanx again – serge 2010-05-17 19:09:06
'addToJavaScriptWindowObject'可能應該連接到'javaScriptWindowObjectCleared'信號,以便在加載新頁面後重新添加。另外,當JavaScript通過'QWebSettings'爲這個頁面禁用時,不幸的是這種方式無法工作,並且我發現沒有辦法禁止它僅用於來自web的javascript。此外,我認爲所添加的對象可以通過網站訪問,所以如果可以加載任何網站,暴露「MainWindow」可能是一個壞主意。 – 2014-04-24 06:34:47