-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathtooltip.py
More file actions
122 lines (95 loc) · 3.88 KB
/
Copy pathtooltip.py
File metadata and controls
122 lines (95 loc) · 3.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
"""
****************************************************************************************************************
Class Tooltips
Provides tooltips for TKInter widgets
Tooltip - Tooltips shared code for Aftercan and ALT-Scann8
This module provides tooltips for both projects. Might be converted to a submodule later on.
Licensed under a MIT LICENSE.
More info in README.md file
****************************************************************************************************************
"""
__author__ = 'Juan Remirez de Esparza'
__copyright__ = "Copyright 2022/24, Juan Remirez de Esparza"
__credits__ = ["Juan Remirez de Esparza"]
__license__ = "MIT"
__module__ = "Tooltips"
__version__ = "1.0.1"
__date__ = "2024-02-19"
__version_highlight__ = "Tooltips - Converted to class"
__maintainer__ = "Juan Remirez de Esparza"
__email__ = "jremirez@hotmail.com"
__status__ = "Development"
import tkinter as tk
class Tooltips():
"""
Singleton class - ensures only one instance is ever created.
"""
_instance = None
DisableTooltips = False
FontSize = 12
screen_width = 0
active_tooltips = []
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self, font_size):
if not hasattr(self, 'initialized'):
Tooltips.FontSize = font_size
Tooltips.DisableTooltips = False
# Create a temporary root window just for obtaining screen information
temp_root = tk.Tk()
# Get the screen height
Tooltips.screen_width = temp_root.winfo_screenwidth()
# Destroy the temporary root window
temp_root.destroy()
self.initialized = True
def format_text(self, text, max_line_width):
words = text.split()
lines = []
current_line = ""
for word in words:
if len(current_line) + len(word) <= max_line_width:
current_line += word + " "
else:
lines.append(current_line.strip())
current_line = word + " "
# Add the last line
if current_line:
lines.append(current_line.strip())
return "\n".join(lines)
def show(self, widget, text):
if widget["state"] == 'disabled' or Tooltips.DisableTooltips:
return
if widget in Tooltips.active_tooltips:
return # Do not show again
else:
Tooltips.active_tooltips.append(widget)
x, y = widget.winfo_pointerxy()
x += 10
y += 10
tooltip_window = tk.Toplevel(widget)
tooltip_window.wm_overrideredirect(True)
#tooltip_window.wm_geometry(f"+{x}+{y}")
formatted_text = self.format_text(text, 60)
label = tk.Label(tooltip_window, text=formatted_text, background="light yellow", relief="solid", borderwidth=1, font=("Arial", Tooltips.FontSize))
if x + label.winfo_reqwidth() > Tooltips.screen_width:
x = Tooltips.screen_width - label.winfo_reqwidth()
tooltip_window.wm_geometry(f"+{x}+{y}")
label.pack()
widget.tooltip_window = tooltip_window
def remove(self, widget, event=None):
if hasattr(widget, 'tooltip_window') and widget.tooltip_window:
widget.tooltip_window.destroy()
widget.tooltip_window = None
if widget in Tooltips.active_tooltips:
Tooltips.active_tooltips.remove(widget)
def schedule_remove(self, widget, event=None):
widget.after(20, lambda: self.remove(widget))
def add(self, widget, tooltip_text):
widget.bind("<Enter>", lambda event: self.show(widget, tooltip_text))
widget.bind("<Leave>", lambda event: self.schedule_remove(widget))
def disable(self):
Tooltips.DisableTooltips = True
def enable(self):
Tooltips.DisableTooltips = False