Andereoo / TkinterWeb

Python bindings for Tkhtml.
MIT License
153 stars 16 forks source link

Currently hovered node not recognized under popup menu (v3.18.5 and later) #59

Closed rodneyboyd closed 1 year ago

rodneyboyd commented 1 year ago

Code:

import tkinter as tk
from tkinter import *
from tkinter import ttk

import tkinterweb
import os.path
import sys
from sys import platform

def show_current_hover(e=None):
    id = html_frame.get_currently_hovered_node_attribute("id")
    tag = html_frame.get_currently_hovered_node_tag()
    text = html_frame.get_currently_hovered_node_text()
    print(id, tag, text)

def add_popup():
    global preview_popup
    preview_popup = Menu(html_frame, tearoff=0)
    preview_popup.add_command(label="Show hover", command=show_current_hover)
    html_frame.bind("<Button-3>", html_menu_popup)

def html_menu_popup(event):
   try:
      preview_popup.tk_popup(event.x_root, event.y_root, 0)
   finally:
      preview_popup.grab_release()     

def main():
    global window
    window = tk.Tk()
    window.title("Simple Browser")

    global my_path
    my_path = os.path.dirname(os.path.abspath(__file__))
    if platform == 'win32':
        my_path = my_path.replace('\\','/')

    global html_frame
    html_frame = tkinterweb.HtmlFrame(window, messages_enabled = False, width=300, height=350)
    global url
    url = 'file:///' + my_path + '/helptest2.html'

    html_frame.grid_propagate(0)
    html_frame.grid(row=0, column=0, sticky=N+S+E+W)
    html_frame.load_file(url, force=False)

    window.bind('<Control-d>', show_current_hover)

    add_popup()
    window.mainloop()

if __name__ == "__main__":
    main()

Sample:

<html>
<head>
<title>Just a test</title>
</head>
<body>
<p>Click me, I'm a <a href="#target">link</a>.</p>

<h2 id="target">I'm a target!</h2>
</body>
</html>

In version 3.18.2, clicking in the h2 element and invoking show_current_hover via the popup menu or via the Ctrl+D keyboard accelerator both print the expected data. In versions 3.18.5 and later, only using the accelerator prints the expected data.

Thanks!

Andereoo commented 1 year ago

I updated TkinterWeb and fixed the problem. In version 3.18.5, I introduced some code that resets the widget's state when the mouse leaves it, so that, for instance, hover flags don't remain on an element after opening a popup. I just added some code that does the opposite when the mouse enters the widget.

I would recommend saving the information about the currently hovered element before opening the menu, as get_currently_hovered_node_attribute, get_currently_hovered_node_tag, and get_currently_hovered_node_text get the node that is under the mouse and not the one clicked on. This means that if the user presses "Show hover" on a part of the popup that is outside of the link's bounds, your code will show the user as having not clicked on a link.

Hope this helps!

rodneyboyd commented 1 year ago

It's working now. Thanks for the update and for the suggestion.

Andereoo commented 1 year ago

No worries!