Can';在Python中找不到DOMEventTarget.add_event_侦听器

Can';在Python中找不到DOMEventTarget.add_event_侦听器,python,events,webkit,webkitgtk,Python,Events,Webkit,Webkitgtk,我将WebKITGTK+项目从C++转换为Python(使用PyGi)。我需要检测页面上的元素何时获得或失去焦点。在C++项目中,我使用这个代码(基于)来执行: 问题是,DOMHTMLInputElement没有add\u event\u listener方法。基于C绑定,它应该是DOMEventTarget的一部分(它扩展了DOMHTMLInputElement),但它与remove\u event\u listener一起丢失,尽管dispatch\u event以某种方式实现了它。这可能是

我将WebKITGTK+项目从C++转换为Python(使用PyGi)。我需要检测页面上的
元素何时获得或失去焦点。在C++项目中,我使用这个代码(基于)来执行:

问题是,
DOMHTMLInputElement
没有
add\u event\u listener
方法。基于C绑定,它应该是
DOMEventTarget
的一部分(它扩展了
DOMHTMLInputElement
),但它与
remove\u event\u listener
一起丢失,尽管
dispatch\u event
以某种方式实现了它。这可能是由于;我不确定


在Python中有什么方法可以做到这一点吗?它不必使用我在C++中使用的相同的方案,我只需要登记一个回调,每次调用在页面上的某些元素上的焦点更改< /p> < p>我的理解是这些函数不会被内省,因此在Python中不可用。我也遇到了同样的问题,并找到了一种解决问题的方法。它确实对我有用

  • 使用javascript来侦听您感兴趣的事件。在javascript事件处理程序函数中,调用警报函数,例如

    警报(“焦点:+node.getId())//或名称或任何有助于python方面识别的内容

  • 在python端,使用警报处理程序获取消息并解析消息以确定是哪个节点

  • 如果不能通过名称/id或xpath识别唯一节点,那么这将不起作用,但是如果控制html,则可以轻松处理此问题


    我的示例代码可以在上找到。查看文件中的警报函数。HTML文件只调用alert,python端解析消息并对其进行操作。

    我最终解决了这一问题,通过作弊并插入C添加了一个事件侦听器,该侦听器将调用回python。我编写了这个简短的C文件,并将其编译成一个共享对象:

    typedef void(*回调)(WebKitDOMNode*node);
    静态bool处理程序(WebKitDOMNode*节点、WebKitDOMEvent*事件、回调cb){
    cb(节点);
    返回true;
    }
    void add_event_listener(WebKitDOMEventTarget*target,以回调为中心,回调模糊){
    webkit\u dom\u event\u target\u add\u event\u listener(目标,“焦点”,G\u回调(处理程序),false,(void*)焦点);
    webkit\u dom\u event\u target\u add\u event\u listener(目标,“模糊”,G\u回调(处理程序),false,(void*)模糊);
    }
    
    我从中窃取了一些代码,以便在Python对象和C指针之间进行转换,并对其进行了一些修改:

    class _PyGObject_Functions(ctypes.Structure):
        _fields_ = [
            ('register_class', ctypes.PYFUNCTYPE(ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int, ctypes.py_object, ctypes.py_object)),
            ('register_wrapper', ctypes.PYFUNCTYPE(ctypes.c_void_p, ctypes.py_object)),
            ('lookup_class', ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_int)),
            ('newgobj', ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_void_p)),
        ]
    
    class PyGObjectCPAI(object):
        def __init__(self):
            PyCObject_AsVoidPtr = ctypes.pythonapi.PyCObject_AsVoidPtr
            PyCObject_AsVoidPtr.restype = ctypes.c_void_p
            PyCObject_AsVoidPtr.argtypes = [ctypes.py_object]
            addr = PyCObject_AsVoidPtr(ctypes.py_object(gi._gobject._PyGObject_API))
            self._api = _PyGObject_Functions.from_address(addr)
    
        def pygobject_new(self, addr):
            return self._api.newgobj(addr)
    
    def cToPython(ptr, capi = PyGObjectCPAI()):
        return capi.pygobject_new(ptr)
    
    def pythonToC(obj):
        return hash(obj)
    
    我编写了一个python事件侦听器:

    def focusChanged(node, focused):
        ....
    
    制作了C-可调用函数(它们需要是全局的,这样它们就不会被垃圾收集):

    并将事件侦听器添加到每个节点:

    document = view.get_dom_document()
    nodes = document.get_elements_by_tag_name('*')
    for i in range(nodes.get_length()):
        node = nodes.item(i)
        if isinstance(node, WebKit.DOMHTMLInputElement) or isinstance(node, WebKit.DOMHTMLTextAreaElement):
            native.add_event_listener(pythonToC(node), focused, blurred)
    
    def focusChanged(node, focused):
        ....
    
    native = ctypes.cdll.LoadLibrary('native.so')
    native.add_event_listener.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
    
    def focused(nodeAddr): focusChanged(cToPython(nodeAddr), True)
    def blurred(nodeAddr): focusChanged(cToPython(nodeAddr), False)
    
    CALLBACK = ctypes.CFUNCTYPE(None, ctypes.c_void_p)
    focused = CALLBACK(focused)
    blurred = CALLBACK(blurred)
    
    document = view.get_dom_document()
    nodes = document.get_elements_by_tag_name('*')
    for i in range(nodes.get_length()):
        node = nodes.item(i)
        if isinstance(node, WebKit.DOMHTMLInputElement) or isinstance(node, WebKit.DOMHTMLTextAreaElement):
            native.add_event_listener(pythonToC(node), focused, blurred)