Search code examples
pythonpython-3.xtkintermenuttk

How to open a menu tied to ttk.Menubutton when hovering over it?


I wanted to make a custom menu bar in Tkinter, but since it was impossible to adjust, I had to make crutches. I made a custom menu from Frame,Button and Menubutton. But I met with a small problem - I can’t open the Menu when hovering over ttk.Menubutton. That is, I need that when hovering over Menubutton the Menu attached to this button opens (simulating clicking on Menubutton). How can this be implemented?

Code

import tkinter as tk
from tkinter import ttk

root = tk.Tk()

root.option_add("*Menu.borderWidth", "0")
root.option_add("*Menu.activeBorderWidth", "0")
root.option_add("*Menu.background", "black")


style = ttk.Style(root)

fr = ttk.Frame(root)

btn_menu = ttk.Menubutton(fr, text='fegvd')
btn_menu.grid(row=0, column=0)

btn =ttk.Button(fr, text='grfbvgfev')
btn.grid(row=0, column=1)

btn_menu_st = ttk.Menubutton(fr, text='Gds')
btn_menu_st.grid(row=0, column=2)

fr.pack(fill='x')


file = tk.Menu(btn_menu, tearoff=0, foreground='white')
file.add_command(label='ГЫГ')

style = tk.Menu(btn_menu_st, tearoff=0, foreground='white')
style.add_command(label='Ugu')

btn_menu.configure(menu=file)
btn_menu_st.configure(menu=style)


root.mainloop()

Solution

  • Maybe there is better idea to achieve it.My idea is to send a mouse event.

    import tkinter as tk
    from tkinter import ttk
    
    root = tk.Tk()
    
    root.option_add("*Menu.borderWidth", "0")
    root.option_add("*Menu.activeBorderWidth", "0")
    root.option_add("*Menu.background", "black")
    
    
    style = ttk.Style(root)
    
    fr = ttk.Frame(root)
    
    btn_menu = ttk.Menubutton(fr, text='fegvd')
    btn_menu.grid(row=0, column=0)
    
    def func1(e):
        e.widget.event_generate("<Button-1>") # send a mouse press event
    
    btn_menu.bind("<Enter>",func1) # when your mouse enter this widget
    btn =ttk.Button(fr, text='grfbvgfev')
    btn.grid(row=0, column=1)
    
    btn_menu_st = ttk.Menubutton(fr, text='Gds')
    btn_menu_st.grid(row=0, column=2)
    
    fr.pack(fill='x')
    
    
    file = tk.Menu(btn_menu, tearoff=0, foreground='white')
    file.add_command(label='ГЫГ')
    
    style = tk.Menu(btn_menu_st, tearoff=0, foreground='white')
    style.add_command(label='Ugu')
    
    btn_menu.configure(menu=file)
    btn_menu_st.configure(menu=style)
    
    
    root.mainloop()
    

    I found .post can be a good way to do.

    import tkinter as tk
    from tkinter import ttk
    
    root = tk.Tk()
    
    root.option_add("*Menu.borderWidth", "0")
    root.option_add("*Menu.activeBorderWidth", "0")
    root.option_add("*Menu.background", "black")
    
    
    style = ttk.Style(root)
    
    fr = ttk.Frame(root)
    
    btn_menu = ttk.Menubutton(fr, text='fegvd')
    btn_menu.grid(row=0, column=0)
    def func1(e):
        file.post(e.widget.winfo_rootx(),e.widget.winfo_rooty()+e.widget.winfo_height())
    
    btn_menu.bind("<Enter>",func1)
    btn =ttk.Button(fr, text='grfbvgfev')
    btn.grid(row=0, column=1)
    
    btn_menu_st = ttk.Menubutton(fr, text='Gds')
    btn_menu_st.grid(row=0, column=2)
    
    fr.pack(fill='x')
    
    
    file = tk.Menu(btn_menu, tearoff=0, foreground='white')
    file.add_command(label='ГЫГ')
    
    style = tk.Menu(btn_menu_st, tearoff=0, foreground='white')
    style.add_command(label='Ugu')
    
    btn_menu.configure(menu=file)
    btn_menu_st.configure(menu=style)
    
    root.mainloop()
    

    But .unpost couldn't work in my PC,I found this question