Make tooltip text show like a table? Make tooltip text show like a table? tkinter tkinter

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()