Button clicked failed when mouse hover tooltip and tooltip destroyed
| BPO | 46180 |
|---|---|
| Nosy | @ned-deily, @serhiy-storchaka, @PySimpleGUI, @Jason990420 |
| Files |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee = None
closed_at = None
created_at = <Date 2021-12-26.10:39:08.666>
labels = ['type-bug', 'expert-tkinter', '3.9', '3.10', '3.11']
title = 'Button clicked failed when mouse hover tooltip and tooltip destroyed'
updated_at = <Date 2022-04-07.20:22:30.083>
user = 'https://github.com/Jason990420'
bugs.python.org fields:
activity = <Date 2022-04-07.20:22:30.083>
actor = 'PySimpleGUI'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Tkinter']
creation = <Date 2021-12-26.10:39:08.666>
creator = 'Jason990420'
dependencies = []
files = ['50607']
hgrepos = []
issue_num = 46180
keywords = []
message_count = 10.0
messages = ['409188', '412263', '412279', '412337', '412351', '412656', '415344', '416675', '416713', '416941']
nosy_count = 5.0
nosy_names = ['ned.deily', 'serhiy.storchaka', 'PySimpleGUI', 'Jason990420', 'jim.wygralak']
pr_nums = []
priority = 'normal'
resolution = None
stage = 'test needed'
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue46180'
versions = ['Python 3.9', 'Python 3.10', 'Python 3.11']
Button no response when clicked if mouse move into tooltip and tooltip destroyed for Python 3.9.9/3.10.1 and tkinter 8.6.12
You can check it by moving mouse into button, then move to tooltip after it shown, then click button and you won't get response for button clicked, but "Leave". It is OK for lower version of Python/tkinter.
import sys
from datetime import datetime
import tkinter as tk
class Tooltip(object):
"""
create a tooltip for a given widget
"""
def __init__(self, widget, text='widget info'):
self.waittime = 500 # miliseconds
self.widget = widget
self.text = text
self.widget.bind("<Enter>", self.enter)
self.widget.bind("<Leave>", self.leave)
self.widget.bind("<ButtonPress>", self.leave)
self.id = None
self.top = None
def enter(self, event=None):
print(now(), "Enter")
self.schedule()
def leave(self, event=None):
print(now(), "Leave")
self.unschedule()
self.hidetip()
def schedule(self):
self.unschedule()
self.id = self.widget.after(self.waittime, self.showtip)
def unschedule(self):
id = self.id
self.id = None
if id:
self.widget.after_cancel(id)
def showtip(self, event=None):
x = y = 0
x, y, cx, cy = self.widget.bbox("insert")
x += self.widget.winfo_rootx() + self.widget.winfo_width()//2
y += self.widget.winfo_rooty() + self.widget.winfo_height()//2
self.top = tk.Toplevel(self.widget)
self.top.wm_overrideredirect(True)
self.top.wm_geometry("+%d+%d" % (x, y))
label = tk.Label(self.top, text=self.text, bd=1, font=font, relief='solid')
label.pack(ipadx=1)
def hidetip(self):
top = self.top
self.top = None
if top:
top.destroy()
def now():
return datetime.now().strftime("%H:%M:%S")
print(f"Python version : {sys.version.split(' ')[0]}")
print(f"tkinter version: {tk.Tcl().eval('info patchlevel')}")
font = ("Courier New", 40)
root = tk.Tk()
button = tk.Button(root, text="button", font=font,
command=lambda:print(now(), 'Button clicked'))
button.pack(padx=10, pady=5)
tooltip = Tooltip(button, 'This is button 1')
root.mainloop()
d:\>python test.py
Python version : 3.10.1
tkinter version: 8.6.12
18:21:52 Enter (Mouse to button)
18:21:54 Leave (mouse to tooltip)
18:21:55 Leave (button clicked get no response)
18:21:57 Leave (button clicked get no response)
18:21:58 Leave (button clicked get no response)
d:\>python test.py
Python version : 3.9.9
tkinter version: 8.6.12
18:22:51 Enter (Mouse to button)
18:22:54 Leave (mouse to tooltip)
18:22:55 Leave (button clicked get no response)
18:22:56 Leave (button clicked get no response)
18:22:57 Leave (button clicked get no response)
d:\>python test.py
Python version : 3.8.10
tkinter version: 8.6.9
18:23:22 Enter (Mouse to button)
18:23:23 Leave (mouse to tooltip)
18:23:23 Enter (mouse stay, and it will repeat `Enter and Leave` again and again)
18:23:24 Leave
...
18:23:28 Enter
18:23:28 Leave
18:23:28 Button clicked (button clicked get response)
18:23:31 Leave
18:23:31 Button clicked (button clicked get response)
18:23:32 Leave
Platform - WIN10
This issue is impacting multiple PySimpleGUI users in particular. One commented today:
"I already spent a day trying to figure out what was happening to my UI when I found this open issue."
Until a fix is found, I'm going to add a specific check for 8.6.12 and disable the tooltip feature and issue a warning to users as to why. Not sure what other options are available at the moment.
Can you say which platforms are affected by this? The OP's example appears to be from a Windows system. Are Unix (X11) and/or macOS versions of Tk affected, too?
The platform is WIN10 which shown at last line in first message. I don't have other platforms to test if ok or not.
I'll do some Linux testing today to see if I can replicate it.
There was another problem reported that only on 8.6.12 on Mac (sorry, don't mean to muddy the waters by mentioning it). The reason I bring it up is that I've not seen a tkinter release have these specific kinds of problems in a very long time and am wondering if something was changed internally that could have an impact on this problem.
I'll report back with what I find on Linux. Thank you SO much for giving this problem some attention.
I'm sorry for not getting back quicker on the Linux testing. I've not figured out how to get 8.6.12 up and running on my Linux environment. I've tried both Python 3.9 and Python 3.10 and neither have 8.6.12.
We've been able to verify this is a problem on Windows, Mac and Linux using the code that Jason posted earlier.
Here's a video of the behavior on Linux. The problem you'll see is that button click events stop being generated.
I'm hoping this is a symptom of a larger problem as there are other problems we've seen on 8.6.12. This is unusual as tkinter has been rock solid since I've been using it over the past few years.
https://user-images.githubusercontent.com/46163555/158422534-964b7edb-f845-468b-adba-57f9139009c4.mp4
DATA: Just chiming in to report that I'm seeing this issue with the following freshly installed: Python 3.10.4 tkinter 8.6.12 PySimpleGUI 4.57.0 OS is Windows 10
As others have report it is related to the cursor entering the tool tip box before clicking the button.
OBSERVATIONS: I've noticed that the tool tip always seems to appear up and to the right of the cursor. If I approach the button by moving the cursor down & left, the tool tip appears when the cursor enters the button, then as I continue to move the cursor to the center of the button I'm moving AWAY FROM the tool tip, and the issue doesn't appear.
However, if I approach the button by moving the cursor up and to the right, the tool tip appears as the cursor enters the button, and it overlaps the button. As I continue to move the cursor to the center of the button, it enters the tool tip box and triggers this fault.
The only 100% effective workaround appears to be not using tooltips. That is a loss of function, and not an acceptable long term solution.
Unfortunately, this is the kind of issue, often the case with tkinter issues, where it is difficult to know where the problem might be. While I know little about the internals of tkinter and Tk, my intuition is that this is most likely a Tk issue and would need to be resolved by the Tk folks. For these kinds of problems, it is usually helpful to try to reproduce the problem using Tcl and Tk directly; I have no idea how difficult that would be in this case. If someone can do so, then it would be much more likely to get the Tk project to look into it (by opening an issue with them). Another ofter useful approach is to ask on the tkinter mailing list or on StackOverflow where people with both tkinter and Tk expertise hang out.
https://mail.python.org/mailman/listinfo/tkinter-discuss
Hi Ned... thank you kindly for the response.
Code was provided on Dec 26, 2021 that reproduces the problem. We've taken the extra step of verifying on Linux and Mac that indeed the problem is on those operating systems as well.
I'm struggling to understand why it's now suggested that the way to get help from the tkinter team is to also produce code directly in TCl/TK directly or that posts on StackOverflow would be of help. It appears to be a bug that's in the lower-level code that happened between releases 8.6.11 and 8.6.12. We're not looking for a workaround, which I suppose is the purpose of posting on StackOverflow, we're looking for a fix.
We're doing our best to follow solid best practices of reproducing problems, providing code to demonstrate the bug, and using the official bug reporting mechanism (bugs.python.org). Any help that can be provided in getting the right persons from the tkinter team responsible for the code is greatly appreciated. Greatly appreciated!
I too encountered this deficiency. Unreliable event notification is as serious as it gets. I had to switch tool-kits. Is there any estimate of when this might be fixed? Thanks.
I am also experiencing this issue which makes me keep my system on older releases of Python to keep my application working as expected, otherwise my UI is unusable due to frequency the buttons do not work when clicking on them. Besides, tooltips are a must on the application requirements for this UI so there is no workaround. I'm very interested on following the progress of this issue. Thanks.
Is there any movement on this problem?
Unfortunately, this is the kind of issue, often the case with tkinter issues, where it is difficult to know where the problem might be.
That's why we included code that replicates the problem, easily. This is not a hard problem to reproduce.
I experienced the same problem when using a Tooltip implementation from https://www.daniweb.com/programming/software-development/code/484591/a-tooltip-class-for-tkinter Starting with Python 3.9 (which include tk 8.6.16) the buttons did not work reliable. When searching for a solution, I arrived here. Searching further, I came to stackoverflow, [https://stackoverflow.com/questions/3221956/how-do-i-display-tooltips-in-tkinter/36221216#36221216] which has this comment:
Some answers use idlelib.tooltip. Following PEP 434, idlelib became mostly privae (allowing changes without prior notice) in 3.6. Immediately, idlelib.Tooltip became idlelib.tooltip. The August 2018 refactoring, applied to 3.6, 3.7, and 3.8, removed the trivial ListboxToolTip subclass and added a new Hovertip subclass. As IDLE maintainer, I might someday incorporate suggestions made below (and others). Since this tool is used externally, I might someday suggest it be moved to tkinter. – Terry Jan Reedy Jun 6, 2022 at 17:44
I tried the idlelib tooltip implementation, and found it fixed the bad behaviour. But I wanted to know the reason, and found the idlelib tooltip avoids overlapping the tooltip area with the parent widget. The comment there says: ` # The tip window must be completely outside the anchor widget;
# otherwise when the mouse enters the tip window we get
# a leave event and it disappears, and then we get an enter
# event and it reappears, and so on forever :-(
#
# Note: This is a simplistic implementation; sub-classes will likely
# want to override this.
When I applied this to my tooltip implementation, the problem was gone. And this also applies to the example code from jason990420 from on Dec 26, 2021 (don't know how to reference a special entry here), if you apply the fix by changing line y += self.widget.winfo_rooty() + self.widget.winfo_height()//2to y += self.widget.winfo_rooty() + self.widget.winfo_height()`
so the tooltip appears completely below the button, the button works as it should.
Hope I could help :-)