QWebPage でフォーカスの変更に対応できるようにする必要があります。私は microFocusChanged() シグナルを使用しましたが、ほとんど望ましい動作が得られましたが、とにかく、どの要素が選択されているかを知る方法がわかりません。ページ上の編集可能な要素がフォーカスを取得または失ったときに、いくつかのアクションを実行したいと考えています。
前もって感謝します
ページ内のHTMLイベントを処理するには、次のようにします。
フォーカス変更ハンドラーを追加するJavaScriptは、すべてのテキスト要素をトラバースし、onfocusハンドラーとonblurハンドラーを追加する必要があります。さらに良いのは、documentElementに単一のハンドラーを追加し、イベントバブリングを使用することです。残念ながら、onblur広告のonfocusはバブルしません。幸いなことに、DOMFocusInおよびDOMFocusOutと呼ばれるバブリングの対応物があります。
これは、ページテキスト要素のフォーカスイン/アウトイベントをキャッチする完全な例です。2つのスロットhandleFocusIn
を宣言handleFocusOut
し、メインウィンドウでJavaScriptから呼び出されるようにし、メインウィンドウを。という名前のグローバルJavaScript変数として登録しますMainWindow
。次に、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 を無効にした状態でも動作させたかったので、 Javascript を使いたくありませんでしたQWebSettings
。私は基本的に2つのアプローチを考えることができます:
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)