Make tooltip text show like a table?
Please see my explained code example below. Hopefully this achieves what you are looking for:
from tkinter import *class App: def __init__(self, root): self.root = root self.labels = [] #array to store labels that we hover over for i in range(3): self.labels.append(Label(self.root, text= "Text"+str(i))) #creates labels that we hover over self.labels[i].pack(fill="both", expand=True) #packs labels that we hover over, needs to be fill="both" and expand=True for some maths later self.labels[i].bind("<Enter>", lambda *args, c=i:self.enter(c)) #bind on enter event self.labels[i].bind("<Leave>", lambda *args, c=i:self.leave(c)) #bind on leave event #for both of the above callbacks we pass in the number which corresponds to the element in the array def enter(self, var): self.var = var self.top = Toplevel(self.root) self.top.wm_overrideredirect(1) #hides the window border and title bar (among other things) self.top.geometry("+%d+%d" % (self.root.winfo_rootx()+self.labels[self.var].winfo_width(), self.root.winfo_rooty()+self.labels[self.var].winfo_y())) #the above line is for placing the toplevel window in the right place #we user self.root.winfo_rootx() and self.root.winfo_rooty() to get the position of the root window on our screen #we then use winfo_width to get the width of the widget we hovered over, and shift the toplevel window to the end of the widget #if you are not using fill="both" and expand=True then you will need to multiply the number by a hard coded value to get it to look "proper" #we also use winfo_y to get the position of the widget we hovered over relative to the window and move the toplevel window down in to positon for i in range(3): #we use these loops to draw the table in the tooltip for c in range(3): Label(self.top, text="Row"+str(i)+"Col"+str(c), borderwidth=1, relief="solid").grid(row=i, column=c) def leave(self, var): self.var = var self.top.destroy()root = Tk()App(root)root.mainloop()
The below will achieve the grid layout you want instead:
from tkinter import *class App: def __init__(self, root): self.root = root self.labels = [] #array to store labels that we hover over for i in range(3): self.labels.append(Label(self.root, text= "Text"+str(i))) #creates labels that we hover over self.labels[i].pack(fill="both", expand=True) #packs labels that we hover over, needs to be fill="both" and expand=True for some maths later self.labels[i].bind("<Enter>", lambda *args, c=i:self.enter(c)) #bind on enter event self.labels[i].bind("<Leave>", lambda *args, c=i:self.leave(c)) #bind on leave event #for both of the above callbacks we pass in the number which corresponds to the element in the array def enter(self, var): self.var = var self.top = Toplevel(self.root) self.top.wm_overrideredirect(1) #hides the window border and title bar (among other things) self.top.geometry("+%d+%d" % (self.root.winfo_rootx()+self.labels[self.var].winfo_width(), self.root.winfo_rooty()+self.labels[self.var].winfo_y())) #the above line is for placing the toplevel window in the right place #we user self.root.winfo_rootx() and self.root.winfo_rooty() to get the position of the root window on our screen #we then use winfo_width to get the width of the widget we hovered over, and shift the toplevel window to the end of the widget #if you are not using fill="both" and expand=True then you will need to multiply the number by a hard coded value to get it to look "proper" #we also use winfo_y to get the position of the widget we hovered over relative to the window and move the toplevel window down in to positon for i in range(4): Grid.rowconfigure(self.top, i, weight=1) for c in range(2): Grid.columnconfigure(self.top, c, weight=1) if i != 3: if c == 0: Label(self.top, text="Heading "+str(i), borderwidth=1, relief="solid").grid(column=i, row=c, sticky=N+S+E+W) else: Label(self.top, text="Col "+str(i)+", Row "+str(c), borderwidth=1, relief="solid").grid(column=i, row=c, sticky=N+S+E+W) else: if c == 0: Label(self.top, text="This is some information and stuff which is rowspanning", borderwidth=1, relief="solid", wraplength=100, justify="left").grid(column=i, row=c, sticky=N+S+E+W, rowspan=2) def leave(self, var): self.var = var self.top.destroy()root = Tk()App(root)root.mainloop()