How to make python tkinter automatically add slashes after every 2 characters - python

from tkinter import *
root=Tk()
root.geometry("400x300")
def e_input():
print(e1.get())
l1=Label(root,text="Enter here:")
l1.place(x=30,y=40)
e1=Entry(root,bd=2,width=25)
e1.place(x=100,y=40)
b1=Button(root,text="Enter",command=e_input)
b1.place(x=250,y=40)
root.mainloop()
In this code, the user manually has to enter the slashes after every 2 characters.
help me out to make that thing by default,
Image attached as to how I needed it to be...
enter image description here

In my example we expand the Entry widget to handle your date format. The validatecommand makes sure that we are entering numbers and that the text matches the format of the regular expression. The key bind handles inserting slashes in the proper position.
import tkinter as tk, re
class DateEntry(tk.Entry):
def __init__(self, master, **kwargs):
tk.Entry.__init__(self, master, **kwargs)
vcmd = self.register(self.validate)
self.bind('<Key>', self.format)
self.configure(validate="all", validatecommand=(vcmd, '%P'))
self.valid = re.compile('^\d{0,2}(\\\\\d{0,2}(\\\\\d{0,4})?)?$', re.I)
def validate(self, text):
if ''.join(text.split('\\')).isnumeric():
return not self.valid.match(text) is None
return False
def format(self, event):
if event.keysym != 'BackSpace':
i = self.index('insert')
if i in [2, 5]:
if self.get()[i:i+1] != '\\':
self.insert(i, '\\')
class Main(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
DateEntry(self, width=10).grid(row=0, column=0)
if __name__ == "__main__":
root = Main()
root.geometry('800x600')
root.title("Date Entry Example")
root.mainloop()

Related

Creating a button in classes. Can someone help why this doesnt work

from tkinter import *
root = Tk()
def main():
Window1 = Window(root, "hello", "500x500",)
class Window:
def __init__(self, root, title, geometry,):
self.root = root
root.title(title)
root.geometry(geometry)
root.mainloop()
class Button(Window):
def __init__(self, message):
self.message = message
super().__init__(root,)
Button(root, text=message,).pack()
root.mainloop()
Button("HI")
main()
One of the two major issues I see is that your Button class is hiding the one that tkinter defines with the same name that would have been available via the from tkinter import *. The second one is that your Button shouldn't be derived from your Window class because subclassing implies there's is an "is a" relationship between the two classes — which is clearly not the case with them.
Below is an object-oriented way to do things that does work:
import tkinter as tk # PEP 8 recommends avoiding `import *`
def main():
root = tk.Tk()
window1 = Window(root, "hello", "500x500")
Button(root, "HI")
root.mainloop()
class Window:
def __init__(self, root, title, geometry):
self.root = root
root.title(title)
root.geometry(geometry)
class Button:
def __init__(self, parent, message):
self.message = message
tk.Button(parent, text=message).pack()
if __name__ == '__main__':
main()
There are a couple of issues.
Firstly, you're creating a subclass of Window called "Button". When you subclass something, it means that it will be of a similar type as it's parent (Window != Button). But more than that, when you define Button, you're actually hiding tkinter's button!
Second, you need to think about the event loop. When working with GUIs, you want to set everything up (where is the button, where are form elements, etc.) before running the mainloop (where possible). You're calling the root.mainloop function in each element, when you should only really call it once (and probably in your main() method).
So how to actually do it? You're code may look something like this
from tkinter import *
class Window:
def __init__(self, root, title, geometry, ):
self.root = root
root.title(title)
root.geometry(geometry)
def add_button(self, label):
btn = Button(self.root, text=label)
btn.pack(side='top')
def main():
root = Tk()
Window1 = Window(root, "hello", "500x500", )
Window1.add_button("Hi!")
root.mainloop()
if __name__ == "__main__":
main()
Here, the window has a method called "add_button", where you can add whatever button you want. Note that it is just creating a new Button object (the parent is "root") and then is "packing" it (feel free to read more about tk's layouts), which puts it in its place
I've also cleaned up the main function and called it under the classic 'if name == "main":' line.
import tkinter as tk
def main():
root = tk.Tk()
window1 = Window(root, "hello", "500x500")
Button(root, "Click me", 2, 2, 10, 5)
root.mainloop()
class Window:
def __init__(self, root, title, geometry):
self.root = root
root.title(title)
root.geometry(geometry)
class Button:
def __init__(self, parent, message, row, column, width, height,):
self.message = message
self.row = row
self.column = column
self.width = width
self.height = height
tk.Button(parent, text=message, height=height, width=width).grid(column=column, row=row)
if __name__ == '__main__':
main()
the grid function isnt working now lol

How to make python automatically put colon in the format of time (HH:MM:SS)

from tkinter import *
root=Tk()
root.geometry("300x300")
def t_input():
print(e1.get())
l1=Label(root,text="Enter here your time:")
l1.place(x=20,y=50)
e1=Entry(root,bd=2,width=25)
e1.place(x=90,y=50)
b1=Button(root,text="Enter",command=t_input)
b1.place(x=240,y=50)
root.mainloop()
This is my code, the user has to input a colon after hour, minute, seconds
Please help me in making it by default
In my example we extend the Entry widget to handle your time format. The validatecommand makes sure we are inputting numbers, and that the text matches the regular expression. The key bind handles insertion of colon.
import tkinter as tk, re
class TimeEntry(tk.Entry):
def __init__(self, master, **kwargs):
tk.Entry.__init__(self, master, **kwargs)
vcmd = self.register(self.validate)
self.bind('<Key>', self.format)
self.configure(validate="all", validatecommand=(vcmd, '%P'))
self.valid = re.compile('^\d{0,2}(:\d{0,2}(:\d{0,2})?)?$', re.I)
def validate(self, text):
if ''.join(text.split(':')).isnumeric():
return not self.valid.match(text) is None
return False
def format(self, event):
if event.keysym != 'BackSpace':
i = self.index('insert')
if i in [2, 5]:
if self.get()[i:i+1] != ':':
self.insert(i, ':')
class Main(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
TimeEntry(self, width=8).grid(row=0, column=0)
if __name__ == "__main__":
root = Main()
root.geometry('800x600')
root.title("Time Entry Example")
root.mainloop()

Creating a bulleted list on a label widget using python tkinter

Is there any way to create a hanging indented list using the tkinter label widget? Note: Using propper standard bullets not * or -.
I have made a class that do what you want:
class BLabel(object):
b = "•"
def __init__(self,master):
import tkinter as tk
self.l = tk.Label(master)
def add_option(self,text):
if self.l.cget("text") == "":
self.l.config(text=self.b+" "+text)
else:
self.l.config(text=self.l.cget("text") +"\n"+ self.b + " "+text)
You can use it like:
lbal = BLabel(master=master)
lbal.add_option("Bullet1") #<-- adding item
lbal.add_option("Bullet2") #<-- adding item
lbal.l.pack() #<-- Packing
Here is an example code:
import tkinter as tk
root = tk.Tk()
class BLabel(object):
b = "•"
def __init__(self,master):
import tkinter as tk
self.l = tk.Label(master)
def add_option(self,text):
if self.l.cget("text") == "":
self.l.config(text=self.b+" "+text)
else:
self.l.config(text=self.l.cget("text") +"\n"+ self.b + " "+text)
lbal = BLabel(master=root)
lbal.add_option("Bullet1")
lbal.add_option("Bullet2")
lbal.l.pack()
Here is the output of above code:
In that way, you can use pack , place or grid. Example:
Grid:
lbal.l.grid(row=0,column=0)
Place:
lbal.l.place(x=0,y=0)
Pack:
lbal.l.pack()
you can use unicode code points, as a rough implementation:
try:
import tkinter as tk
except ImportError:
import Tkinter as tk
class BulletLabel(tk.Label):
def __init__(self, master, *args, **kwargs):
text = kwargs.pop('text', '')
kwargs['text'] = self.bulletise(text)
tk.Label.__init__(self, master, *args, **kwargs)
def bulletise(self, text):
if len(text) == 0: # no text so no bullets
return ''
lines = text.split('\n')
parts = []
for line in lines: # for each line
parts.extend(['\u2022', line, '\n']) # prepend bullet and re append newline removed by split
return ''.join(parts)
def configure(self, *args, **kwargs):
text = kwargs.pop('text', '')
if text != '':
kwargs['text'] = self.bulletise(text)
tk.Label.configure(*args, **kwargs)
root = tk.Tk()
blabel = BulletLabel(root, text='one\ntwo\nthree')
blabel.pack()
root.mainloop()
You'd be better off with a message widget, which is a label widget designed to show text with multiple lines. For your bullets you can use a unicode string. For example:
import tkinter as tk
root = tk.Tk()
point = '\u2022'
msg = tk.Message(root, text='Hello\n%s World.' % point)
msg.pack()

Buiding a BackSpace and Enter function in custom Python tkinter program

I'm building a simulator program on python 3 Tkinter window. The progress is now disrupt due to a bug in the input program I build myself.
The broken code that I'm working on right now:
from tkinter import *
root = Tk()
prompt = ' Press any key '
label1 = Label(root, text=prompt, bg='black', fg='green')
label1.grid(row=0, column=0)
prompt2=''
def key(event):
global prompt2
if event.char == event.keysym:
prompt2 = prompt2 + event.char
elif len(event.char) == 1:
prompt2 = prompt2 + event.char
else:
pass
label1.config(text=prompt2)
root.bind_all('<Key>', key)
root.update()
root.mainloop()
So, what I want to do (and trying to do) is:
Build a function that allow the user to use BackSpace and stop them from using Enter (as I don't want them to move to a new line).
Set a variable to True, give the program a signal for when to start (taking input) and when to stop.
But I can't seem to do this. Any suggestions for 1 or 2? Please tell me in the comment section.
Thanks in advance!
Why are you comparing event.char to event.keysym? That will always be True for printable characters, and always be False for character sequences and special characters (like ⇦ and ↲).
How about this (untested)?
import string
import tkinter as tk
# See side note 1
def key_event(label, event):
label_text = label.cget("text")
if event.keysym == "backspace":
label.config(text=label_text[:-1])
elif event.keysym == "return":
# Disallow 'return'
pass
elif event.char in string.ascii_lowercase:
# Character is an ASCII letter
label.config(text=label_text + event.char)
def main():
root = tk.Tk()
prompt = " Press any key "
label = tk.Label(root, text=prompt, bg="black", fg="green")
label.grid(row=0, column=0)
label.bind("<Key>", lambda e: key_event(label, e))
# See side note 2
label.focus()
# Give keyboard focus
root.mainloop()
Side note 1: avoid using wildcard imports (from ... import *). Instead, alias tkinter 'as' tk:
import tkinter as tk
root = tk.Tk()
...
Side note 2: avoid using global variables, prefer using a class (provided you know how to use them properly, see below section for an example), or for really small pieces of code, share variables using lambdas like I did.
import string
import tkinter as tk
class EditableLabel(tk.Label):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.bind("<Key>", self._key_event)
def _key_event(self, event):
keysym, char = event.keysym, event.char
text = self.cget("text")
if keysym == "backspace":
self.config(text=text[:-1])
elif keysym == "return":
pass
elif char in string.ascii_lowercase + string.digits:
self.config(text=text + char)
class MyApplication(tk.Frame):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._add_and_draw_widgets()
def _add_and_draw_widgets(self):
for i in range(3):
EditableLabel(self, text="Label #{}".format(i)).grid(column=0, row=i)
def main():
root = tk.Tk()
app = MyApplication(root)
app.grid(column=0, row=0)
root.mainloop()
if __name__ == "__main__":
main()

Display message when hovering over something with mouse cursor in Python

I have a GUI made with TKinter in Python. I would like to be able to display a message when my mouse cursor goes, for example, on top of a label or button. The purpose of this is to explain to the user what the button/label does or represents.
Is there a way to display text when hovering over a tkinter object in Python?
I think this would meet your requirements.
Here's what the output looks like:
First, A class named ToolTip which has methods showtip and hidetip is defined as follows:
from tkinter import *
class ToolTip(object):
def __init__(self, widget):
self.widget = widget
self.tipwindow = None
self.id = None
self.x = self.y = 0
def showtip(self, text):
"Display text in tooltip window"
self.text = text
if self.tipwindow or not self.text:
return
x, y, cx, cy = self.widget.bbox("insert")
x = x + self.widget.winfo_rootx() + 57
y = y + cy + self.widget.winfo_rooty() +27
self.tipwindow = tw = Toplevel(self.widget)
tw.wm_overrideredirect(1)
tw.wm_geometry("+%d+%d" % (x, y))
label = Label(tw, text=self.text, justify=LEFT,
background="#ffffe0", relief=SOLID, borderwidth=1,
font=("tahoma", "8", "normal"))
label.pack(ipadx=1)
def hidetip(self):
tw = self.tipwindow
self.tipwindow = None
if tw:
tw.destroy()
def CreateToolTip(widget, text):
toolTip = ToolTip(widget)
def enter(event):
toolTip.showtip(text)
def leave(event):
toolTip.hidetip()
widget.bind('<Enter>', enter)
widget.bind('<Leave>', leave)
The widget is where you want to add the tip. For example, if you want the tip when you hover over a button or entry or label, the instance of the same should be provided at the call time.
Quick note: the code above uses from tkinter import *
which is not suggested by some of the programmers out there, and they have valid points. You might want to make necessary changes in such case.
To move the tip to your desired location, you can change x and y in the code.
The function CreateToolTip() helps to create this tip easily. Just pass the widget and string you want to display in the tipbox to this function, and you're good to go.
This is how you call the above part:
button = Button(root, text = 'click mem')
button.pack()
CreateToolTip(button, text = 'Hello World\n'
'This is how tip looks like.'
'Best part is, it\'s not a menu.\n'
'Purely tipbox.')
Do not forget to import the module if you save the previous outline in different python file, and don't save the file as CreateToolTip or ToolTip to avoid confusion.
This post from Fuzzyman shares some similar thoughts, and worth checking out.
You need to set a binding on the <Enter> and <Leave> events.
Note: if you choose to pop up a window (ie: a tooltip) make sure you don't pop it up directly under the mouse. What will happen is that it will cause a leave event to fire because the cursor leaves the label and enters the popup. Then, your leave handler will dismiss the window, your cursor will enter the label, which causes an enter event, which pops up the window, which causes a leave event, which dismisses the window, which causes an enter event, ... ad infinitum.
For simplicity, here's an example that updates a label, similar to a statusbar that some apps use. Creating a tooltip or some other way of displaying the information still starts with the same core technique of binding to <Enter> and <Leave>.
import Tkinter as tk
class Example(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.l1 = tk.Label(self, text="Hover over me")
self.l2 = tk.Label(self, text="", width=40)
self.l1.pack(side="top")
self.l2.pack(side="top", fill="x")
self.l1.bind("<Enter>", self.on_enter)
self.l1.bind("<Leave>", self.on_leave)
def on_enter(self, event):
self.l2.configure(text="Hello world")
def on_leave(self, enter):
self.l2.configure(text="")
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(side="top", fill="both", expand="true")
root.mainloop()
You can refer to this- HoverClass
It is exactly what you need. Nothing more, nothing less
from Tkinter import *
import re
class HoverInfo(Menu):
def __init__(self, parent, text, command=None):
self._com = command
Menu.__init__(self,parent, tearoff=0)
if not isinstance(text, str):
raise TypeError('Trying to initialise a Hover Menu with a non string type: ' + text.__class__.__name__)
toktext=re.split('\n', text)
for t in toktext:
self.add_command(label = t)
self._displayed=False
self.master.bind("<Enter>",self.Display )
self.master.bind("<Leave>",self.Remove )
def __del__(self):
self.master.unbind("<Enter>")
self.master.unbind("<Leave>")
def Display(self,event):
if not self._displayed:
self._displayed=True
self.post(event.x_root, event.y_root)
if self._com != None:
self.master.unbind_all("<Return>")
self.master.bind_all("<Return>", self.Click)
def Remove(self, event):
if self._displayed:
self._displayed=False
self.unpost()
if self._com != None:
self.unbind_all("<Return>")
def Click(self, event):
self._com()
Example app using HoverInfo:
from Tkinter import *
from HoverInfo import HoverInfo
class MyApp(Frame):
def __init__(self, parent=None):
Frame.__init__(self, parent)
self.grid()
self.lbl = Label(self, text='testing')
self.lbl.grid()
self.hover = HoverInfo(self, 'while hovering press return \n for an exciting msg', self.HelloWorld)
def HelloWorld(self):
print('Hello World')
app = MyApp()
app.master.title('test')
app.mainloop()
Screenshot:
I have a very hacky solution but it has some advantages over the current answers so I figured I would share it.
lab=Label(root,text="hover me")
lab.bind("<Enter>",popup)
def do_popup(event):
# display the popup menu
root.after(1000, self.check)
popup = Menu(root, tearoff=0)
popup.add_command(label="Next")
popup.tk_popup(event.x_root, event.y_root, 0)
def check(event=None):
x, y = root.winfo_pointerxy()
widget = root.winfo_containing(x, y)
if widget is None:
root.after(100, root.check)
else:
leave()
def leave():
popup.delete(0, END)
The only real issue with this is it leaves behind a small box that moves focus away from the main window
If anyone knows how to solve these issues let me know
If anyone is on Mac OSX and tool tip isn't working, check out the example in:
https://github.com/python/cpython/blob/master/Lib/idlelib/tooltip.py
Basically, the two lines that made it work for me on Mac OSX were:
tw.update_idletasks() # Needed on MacOS -- see #34275.
tw.lift() # work around bug in Tk 8.5.18+ (issue #24570)
Here is a simple solution to your problem that subclasses the tk.Button object. We make a special class that tk.Button inherits from, giving it tooltip functionality. The same for tk.Labels.
I don't know what would be cleanest and the easiest way to maintain code for keeping track of the text that goes into the tooltips. I present here one way, in which I pass unique widget IDs to MyButtons, and access a dictionary for storing the tooltip texts. You could store this file as a JSON, or as a class attribute, or as a global variable (as below). Alternatively, perhaps it would be better to define a setter method in MyButton, and just call this method every time you create a new widget that should have a tooltip. Although you would have to store the widget instance in a variable, adding one extra line for all widgets to include.
One drawback in the code below is that the self.master.master syntax relies on determining the "widget depth". A simple recursive function will catch most cases (only needed for entering a widget, since by definition you leave somewhere you once were).
Anyway, below is a working MWE for anyone interested.
import tkinter as tk
tooltips = {
'button_hello': 'Print a greeting message',
'button_quit': 'Quit the program',
'button_insult': 'Print an insult',
'idle': 'Hover over button for help',
'error': 'Widget ID not valid'
}
class ToolTipFunctionality:
def __init__(self, wid):
self.wid = wid
self.widet_depth = 1
self.widget_search_depth = 10
self.bind('<Enter>', lambda event, i=1: self.on_enter(event, i))
self.bind('<Leave>', lambda event: self.on_leave(event))
def on_enter(self, event, i):
if i > self.widget_search_depth:
return
try:
cmd = f'self{".master"*i}.show_tooltip(self.wid)'
eval(cmd)
self.widget_depth = i
except AttributeError:
return self.on_enter(event, i+1)
def on_leave(self, event):
cmd = f'self{".master" * self.widget_depth}.hide_tooltip()'
eval(cmd)
class MyButton(tk.Button, ToolTipFunctionality):
def __init__(self, parent, wid, **kwargs):
tk.Button.__init__(self, parent, **kwargs)
ToolTipFunctionality.__init__(self, wid)
class MyLabel(tk.Label, ToolTipFunctionality):
def __init__(self, parent, wid, **kwargs):
tk.Label.__init__(self, parent, **kwargs)
ToolTipFunctionality.__init__(self, wid)
class Application(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.tooltip = tk.StringVar()
self.tooltip.set(tooltips['idle'])
self.frame = tk.Frame(self, width=50)
self.frame.pack(expand=True)
MyLabel(self.frame, '', text='One Cool Program').pack()
self.subframe = tk.Frame(self.frame, width=40)
self.subframe.pack()
MyButton(self.subframe, 'button_hello', text='Hello!', command=self.greet, width=20).pack()
MyButton(self.subframe, 'button_insutl', text='Insult', command=self.insult, width=20).pack()
MyButton(self.subframe, 'button_quit', text='Quit', command=self.destroy, width=20).pack()
tk.Label(self.subframe, textvar=self.tooltip, width=20).pack()
def show_tooltip(self, wid):
try:
self.tooltip.set(tooltips[wid])
except KeyError:
self.tooltip.set(tooltips['error'])
def hide_tooltip(self):
self.tooltip.set(tooltips['idle'])
def greet(self):
print('Welcome, Fine Sir!')
def insult(self):
print('You must be dead from the neck up')
if __name__ == '__main__':
app = Application()
app.mainloop()
The best way I have found to create a popup help window is to use the tix.Balloon. I have modified it below to make it look better and show an example (note the use of tix.Tk):
import tkinter as tk
import tkinter.tix as tix
class Balloon(tix.Balloon):
# A modified tix popup balloon (to change the default delay, bg and wraplength)
init_after = 1250 # Milliseconds
wraplength = 300 # Pixels
def __init__(self, master):
bg = root.cget("bg")
# Call the parent
super().__init__(master, initwait=self.init_after)
# Change background colour
for i in self.subwidgets_all():
i.config(bg=bg)
# Modify the balloon label
self.message.config(wraplength=self.wraplength)
root = tix.Tk()
l = tk.Label(root, text="\n".join(["text"] * 5))
l.pack()
b = Balloon(root.winfo_toplevel())
b.bind_widget(l, balloonmsg="Some random text")
root.mainloop()
OLD ANSWER:
Here is an example using <enter> and <leave> as #bryanoakley suggested with a toplevel (with overridedirect set to true). Use the hover_timer class for easy use of this. This needs the widget and help-text (with an optional delay argument - default 0.5s) and can be easily called just by initiating the class and then cancelling it.
import threading, time
from tkinter import *
class hover_window (Toplevel):
def __init__ (self, coords, text):
super ().__init__ ()
self.geometry ("+%d+%d" % (coords [0], coords [1]))
self.config (bg = "white")
Label (self, text = text, bg = "white", relief = "ridge", borderwidth = 3, wraplength = 400, justify = "left").grid ()
self.overrideredirect (True)
self.update ()
self.bind ("<Enter>", lambda event: self.destroy ())
class hover_timer:
def __init__ (self, widget, text, delay = 2):
self.wind, self.cancel_var, self.widget, self.text, self.active, self.delay = None, False, widget, text, False, delay
threading.Thread (target = self.start_timer).start ()
def start_timer (self):
self.active = True
time.sleep (self.delay)
if not self.cancel_var: self.wind = hover_window ((self.widget.winfo_rootx (), self.widget.winfo_rooty () + self.widget.winfo_height () + 20), self.text)
self.active = False
def delayed_stop (self):
while self.active: time.sleep (0.05)
if self.wind:
self.wind.destroy ()
self.wind = None
def cancel (self):
self.cancel_var = True
if not self.wind: threading.Thread (target = self.delayed_stop).start ()
else:
self.wind.destroy ()
self.wind = None
def start_help (event):
# Create a new help timer
global h
h = hover_timer (l, "This is some additional information.", 0.5)
def end_help (event):
# If therre is one, end the help timer
if h: h.cancel ()
if __name__ == "__main__":
# Create the tkinter window
root = Tk ()
root.title ("Hover example")
# Help class not created yet
h = None
# Padding round label
Frame (root, width = 50).grid (row = 1, column = 0)
Frame (root, height = 50).grid (row = 0, column = 1)
Frame (root, width = 50).grid (row = 1, column = 2)
Frame (root, height = 50).grid (row = 2, column = 1)
# Setup the label
l = Label (root, text = "Hover over me for information.", font = ("sans", 32))
l.grid (row = 1, column = 1)
l.bind ("<Enter>", start_help)
l.bind ("<Leave>", end_help)
# Tkinter mainloop
root.mainloop ()
I wanted to contribute to the answer of #squareRoot17 as he inspired me to shorten his code while providing the same functionality:
import tkinter as tk
class ToolTip(object):
def __init__(self, widget, text):
self.widget = widget
self.text = text
def enter(event):
self.showTooltip()
def leave(event):
self.hideTooltip()
widget.bind('<Enter>', enter)
widget.bind('<Leave>', leave)
def showTooltip(self):
self.tooltipwindow = tw = tk.Toplevel(self.widget)
tw.wm_overrideredirect(1) # window without border and no normal means of closing
tw.wm_geometry("+{}+{}".format(self.widget.winfo_rootx(), self.widget.winfo_rooty()))
label = tk.Label(tw, text = self.text, background = "#ffffe0", relief = 'solid', borderwidth = 1).pack()
def hideTooltip(self):
tw = self.tooltipwindow
tw.destroy()
self.tooltipwindow = None
This class can then be imported and used as:
import tkinter as tk
from tooltip import ToolTip
root = tk.Tk()
your_widget = tk.Button(root, text = "Hover me!")
ToolTip(widget = your_widget, text = "Hover text!")
root.mainloop()

Categories

Resources