如何在QWebView / QWebPage中获得焦点元素?
我需要能够对QWebPage中的焦点变化做出反应。 我用microFocusChanged()信号,它给了我几乎所需的行为,但无论如何,我不知道如何知道哪个元素被选中。 我想在页面上的任何可编辑元素获取或失去焦点时执行一些操作。
先谢谢你
要处理页面内的任何HTML事件,请执行以下操作:
JavaScript添加焦点更改处理程序应该遍历所有文本元素并添加onfocus和onblur处理程序。 更好的做法是将单个处理程序添加到documentElement并使用事件冒泡。 不幸的是,onblur广告聚焦不起泡。 幸运的是,它们有一个叫做DOMFocusIn和DOMFocusOut的冒泡对应物。
  这是一个完整的检查页面文本元素的焦点输入/输出事件。  它在主窗口上声明了两个插槽handleFocusIn和handleFocusOut ,以便从JavaScripts中调用并将主窗口注册为名为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)
