Search code examples
pythonpython-3.xtkinterstylesttkwidgets

Why does the indicator in ttk.Menubutton not disappear?


I wrote code with ttk.Menubutton, but I met a problem - the indicator does not disappear, although it was possible to remove it in tk.Menubutton.

Code

ttk.Menubutton:

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)


menu = tk.Menu(root)

btn_menu = ttk.Menubutton(root, text='fegvd')
btn_menu.pack()

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

style.configure('TMenubutton', background='black', foreground='white', indicatoron=0, menu=file, direction='delow', state='active')

root.mainloop()

tk.Menubutton:

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


menu = tk.Menu(root)

btn_menu = tk.Menubutton(root, text='fegvd')
btn_menu.pack()


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

btn_menu.configure(background='black', foreground='white', indicator=0, menu=file, state='active')

root.mainloop()

Screenshots

ttk.Menubutton

enter image description here

tk.Menubutton

enter image description here

How to fix it?


Solution

  • The indicator does not disappear because the ttk theme does not have an indicatoron option and style.configure() simply ignores the invalid options instead of raising an error.

    However you probably can get rid of the indicator using style.layout(). The solution below does not work with the default theme on OSX, but it works for 'clam' and 'alt'. You seem to be using Windows so maybe it will also work for the Windows theme, otherwise you can change theme.

    If you look at the output of style.layout('TMenubutton'), you will have something like

    [('Menubutton.border',
      {'sticky': 'nswe',
       'children': [('Menubutton.focus',
         {'sticky': 'nswe',
          'children': [('Menubutton.indicator', {'side': 'right', 'sticky': ''}),
           ('Menubutton.padding',
            {'expand': '1',
             'sticky': 'we',
             'children': [('Menubutton.label',
               {'side': 'left', 'sticky': ''})]})]})]})]
    

    To get rid of the 'Menubutton.indicator', you can just remove it from the layout:

    style.layout('TMenubutton', [('Menubutton.border',
      {'sticky': 'nswe',
       'children': [('Menubutton.focus',
         {'sticky': 'nswe',
          'children': [
           ('Menubutton.padding',
            {'expand': '1',
             'sticky': 'we',
             'children': [('Menubutton.label',
               {'side': 'left', 'sticky': ''})]})]})]})])
    

    If you need other menubuttons with an indicator, you can replace 'TMenubutton' by a custom name, e.g. 'noindicator.TMenubutton' and do btn_menu.configure(style='noindicator.TMenubutton') to use this layout for this particular menubutton.