1010from ttkwidgets .utilities import get_assets_directory
1111
1212
13- class Balloon (ttk .Frame ):
13+ class Tooltip (ttk .Frame ):
1414 """Simple help hover balloon."""
1515
1616 def __init__ (self , master = None , headertext = "Help" , text = "Some great help is displayed here." , width = 200 , timeout = 1 ,
17- background = "#fef9cd" , ** kwargs ):
17+ background = "#fef9cd" , offset = ( 2 , 2 ), showheader = True , static = False , ** kwargs ):
1818 """
19- Create a Balloon.
19+ Create a Tooltip
2020
21- :param master: widget to bind the Balloon to
21+ :param master: widget to bind the Tooltip to
2222 :type master: widget
2323 :param headertext: text to show in window header
2424 :type headertext: str
2525 :param text: text to show as help text
2626 :type text: str
2727 :param width: width of the window
2828 :type width: int
29- :param timeout: timeout in seconds to wait until the Balloon is shown
29+ :param timeout: timeout in seconds to wait until the Tooltip is shown
3030 :type timeout: float
31- :param background: background color of the Balloon
31+ :param background: background color of the Tooltip
3232 :type background: str
33+ :param offset: The offset from the mouse position the Ballon shows up
34+ :type offset: Tuple[int, int]
35+ :param showheader: Whether to display the header with image
36+ :type showheader: bool
37+ :param static: Whether to display the tooltip with static
38+ position. When the position is set to static, the balloon
39+ will always appear an offset from the bottom right corner of
40+ the widget.
41+ :type static: bool
3342 :param kwargs: keyword arguments passed on to the :class:`ttk.Frame` initializer
3443 """
3544 ttk .Frame .__init__ (self , master , ** kwargs )
@@ -47,11 +56,21 @@ def __init__(self, master=None, headertext="Help", text="Some great help is disp
4756 self .__headertext = headertext
4857 self .__text = text
4958 self .__width = width
59+ self .__offset = offset
60+ self .__showheader = showheader
61+ self .__static = static
62+
5063 self .master = master
5164 self ._id = None
5265 self ._timeout = timeout
53- self .master .bind ("<Enter>" , self ._on_enter )
54- self .master .bind ("<Leave>" , self ._on_leave )
66+
67+ self ._bind_to_master ()
68+
69+ def _bind_to_master (self ):
70+ """Bind the Balloon widget to the master widget's events"""
71+ self .master .bind ("<Enter>" , self ._on_enter , "add" )
72+ self .master .bind ("<Leave>" , self ._on_leave , "add" )
73+ self .master .bind ("<ButtonPress>" , self ._on_leave , "add" )
5574
5675 def __getitem__ (self , key ):
5776 return self .cget (key )
@@ -62,7 +81,8 @@ def __setitem__(self, key, value):
6281 def _grid_widgets (self ):
6382 """Place the widgets in the Toplevel."""
6483 self ._canvas .grid (sticky = "nswe" )
65- self .header_label .grid (row = 1 , column = 1 , sticky = "nswe" , pady = 5 , padx = 5 )
84+ if self .__showheader is True :
85+ self .header_label .grid (row = 1 , column = 1 , sticky = "nswe" , pady = 5 , padx = 5 )
6686 self .text_label .grid (row = 3 , column = 1 , sticky = "nswe" , pady = 6 , padx = 5 )
6787
6888 def _on_enter (self , event ):
@@ -80,9 +100,10 @@ def _on_leave(self, event):
80100
81101 def show (self ):
82102 """
83- Create the Toplevel widget and its child widgets to show in the spot of the cursor.
103+ Create the Toplevel and its children to show near the cursor
84104
85- This is the callback for the delayed :obj:`<Enter>` event (see :meth:`~Balloon._on_enter`).
105+ This is the callback for the delayed :obj:`<Enter>` event
106+ (see :meth:`~Tooltip._on_enter`).
86107 """
87108 self ._toplevel = tk .Toplevel (self .master )
88109 self ._canvas = tk .Canvas (self ._toplevel , background = self .__background )
@@ -93,11 +114,17 @@ def show(self):
93114 self ._toplevel .attributes ("-topmost" , True )
94115 self ._toplevel .overrideredirect (True )
95116 self ._grid_widgets ()
96- x , y = self .master .winfo_pointerxy ()
117+ if self .__static is True :
118+ x , y = self .master .winfo_rootx (), self .master .winfo_rooty ()
119+ w , h = self .master .winfo_width (), self .master .winfo_height ()
120+ x , y = x + w , y + h
121+ else :
122+ x , y = self .master .winfo_pointerxy ()
97123 self ._canvas .update ()
98124 # Update the Geometry of the Toplevel to update its position and size
99- self ._toplevel .geometry ("{0}x{1}+{2}+{3}" .format (self ._canvas .winfo_width (), self ._canvas .winfo_height (),
100- x + 2 , y + 2 ))
125+ self ._toplevel .geometry ("{0}x{1}+{2}+{3}" .format (
126+ self ._canvas .winfo_width (), self ._canvas .winfo_height (),
127+ x + self .__offset [0 ], y + self .__offset [1 ]))
101128
102129 def cget (self , key ):
103130 """
@@ -107,7 +134,8 @@ def cget(self, key):
107134 :type key: str
108135 :return: value of the option
109136
110- To get the list of options for this widget, call the method :meth:`~Balloon.keys`.
137+ To get the list of options for this widget, call the method
138+ :meth:`~Tooltip.keys`.
111139 """
112140 if key == "headertext" :
113141 return self .__headertext
@@ -119,21 +147,31 @@ def cget(self, key):
119147 return self ._timeout
120148 elif key == "background" :
121149 return self .__background
150+ elif key == "offset" :
151+ return self .__offset
152+ elif key == "showheader" :
153+ return self .__showheader
154+ elif key == "static" :
155+ return self .__static
122156 else :
123157 return ttk .Frame .cget (self , key )
124158
125159 def config (self , ** kwargs ):
126160 """
127161 Configure resources of the widget.
128162
129- To get the list of options for this widget, call the method :meth:`~Balloon.keys`.
130- See :meth:`~Balloon.__init__` for a description of the widget specific option.
163+ To get the list of options for this widget, call the method
164+ :meth:`~Tooltip.keys`. See :meth:`~Tooltip.__init__` for a
165+ description of the widget specific option.
131166 """
132167 self .__headertext = kwargs .pop ("headertext" , self .__headertext )
133168 self .__text = kwargs .pop ("text" , self .__text )
134169 self .__width = kwargs .pop ("width" , self .__width )
135170 self ._timeout = kwargs .pop ("timeout" , self ._timeout )
136171 self .__background = kwargs .pop ("background" , self .__background )
172+ self .__offset = kwargs .pop ("offset" , self .__offset )
173+ self .__showheader = kwargs .pop ("showheader" , self .__showheader )
174+ self .__static = kwargs .pop ("static" , self .__static )
137175 if self ._toplevel :
138176 self ._on_leave (None )
139177 self .show ()
@@ -143,5 +181,5 @@ def config(self, **kwargs):
143181
144182 def keys (self ):
145183 keys = ttk .Frame .keys (self )
146- keys .extend (["headertext" , "text" , "width" , "timeout" , "background" ])
184+ keys .extend (["headertext" , "text" , "width" , "timeout" , "background" , "offset" , "showheader" , "static" ])
147185 return keys
0 commit comments