Self Made Tkinter Popup Menu Python Self Made Tkinter Popup Menu Python tkinter tkinter

Self Made Tkinter Popup Menu Python


I would do this using a tracking variable.

We can first assign None to f as a way to check if f is currently set up.

If f is not None then we create frame and button. Then when the function is activated we can run function and destroy the frame the button was in. This also destroys the button and then we set f back to None for out next use.

Take a look at the below reworked example.Let me know if you have any questions.

from tkinter import *root = Tk()w = Label(root, text="Right-click to display menu", width=40, height=20)w.place(x=0)f = None # Tracking F to see if it is None or not.def function1():    global f    print('function1 activated')    # add this to the end of the function to destroy the frame and reset f    if f != None:        f.destroy()        f = Nonedef open_popup(event):    global f    # if f is None then create frame and button else don't    if f == None:        f = Frame(root,width=80,height=60,background='green')        f.place(x=event.x, y=event.y)        b2 = Button(f,text='function',command=function1)        b2.pack()    else:        print("Can't open popup menu")w.bind("<Button-3>", open_popup)b = Button(root, text="Quit", command=root.destroy)b.pack()root.mainloop()


I found a way to do this without modifying so much the code, the idea of the tracking variable was good but doesn't solve all the problems, and this code does.

from tkinter import *root = Tk()w = Label(root, text="Right-click to display menu", width=40, height=20)w.pack()def function1():    print('function1 activated')    try:        f.place_forget()    except:        pass# create a menuf = Frame(root,width=80,height=60,background='green')b2 = Button(f,text='function',command=function1)b2.place(x=0,y=5)def open_popup(event):     try:        f.place(x=event.x, y=event.y)        root.after(1)        f.focus_set()    except:        passdef close_popup(event):    try:        f.place_forget()        root.after(1)        w.unbind_all("<Button-1>")    except:        passdef enable_depopup(event):    w.bind_all("<Button-1>",close_popup)def disable_depopup(event):    w.unbind_all("<Button-1>")w.bind("<Button-3>", open_popup)w.bind("<Motion>", enable_depopup)f.bind("<Motion>", disable_depopup)b = Button(root, text="Quit", command=root.destroy)b.pack()root.mainloop()

In this way, everytime I move the mouse over the parent window, the <Button-1> of the mouse is binded to close the popup menu.And doing a trick, that is place the button of the menu a few pixels down, this let the mouse pass through the popup frame to reach the button and disable the <Button-1> binding letting me click the button.The function of the button activate the place_forget method of the frame, so everything works correctly.