Как изменить цвет объекта tk.Menu?

Поэтому я сделал этот текстовый редактор с помощью tkinter и python. Он имеет строку меню с раскрывающимся меню «Файл».

Вот снимок экрана: введите здесь описание изображения

Я пытался изменить его цвет, но что бы я ни делал, ничего не работает.

Вот фрагмент кода:

class MenuBar:
    def __init__(self, mainClass):
        fontSpecs = ("ubuntu", 9)

        menuBar = tk.Menu(mainClass.win, font=fontSpecs)
        mainClass.win.config(bg="#3C3F41", menu=menuBar)

        fileDropDown = tk.Menu(menuBar, font=fontSpecs, tearoff=0, fg="#AFB1B3", bg="#313335")
        fileDropDown.add_command(label="New File", command=mainClass.NewFile, accelerator="Ctrl+N")
        fileDropDown.add_command(label="Open File", command=mainClass.OpenFile, accelerator="Ctrl+O")
        fileDropDown.add_command(label="Save", command=mainClass.Save, accelerator="Ctrl+S")
        fileDropDown.add_command(label="Save As", command=mainClass.SaveAs, accelerator="Ctrl+Shift+S")
        fileDropDown.add_separator()
        fileDropDown.add_command(label="Exit", command=mainClass.Exit)

        menuBar.add_cascade(label="File", menu=fileDropDown)

Вот метод __init__() основного класса:

class TextEditor:
    def __init__(self, win: tk.Tk):
        win.title(f"Untitled - {name}")
        win.geometry("1100x600")

        fontSpecs = ("ubuntu", 12)

        self.win = win
        self.fileName = None

        self.textArea = tk.Text(self.win, font=fontSpecs, insertbackground="#AFB1B3", fg="#AFB1B3", bg="#313335")
        self.scroll = tk.Scrollbar(self.win, command=self.textArea.yview())
        self.textArea.configure(yscrollcommand=self.scroll.set)
        self.textArea.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        font = tk_font.Font(font=self.textArea["font"])
        tab = font.measure("    ")  # 4 empty spaces
        self.textArea.config(tabs=tab)

        self.scroll.pack(side=tk.RIGHT, fill=tk.Y)

        self.menuBar = MenuBar(self)

Если вам нужна дополнительная информация, пожалуйста, спросите.


person Jimothy Cardotha    schedule 01.08.2020    source источник
comment
Если можно, добавьте реальное изображение, а не ссылку.   -  person cs1349459    schedule 01.08.2020
comment
Пожалуйста, отредактируйте свой вопрос и укажите минимально воспроизводимый пример.   -  person martineau    schedule 01.08.2020
comment
Вы можете создать его самостоятельно из Frame и с помощью menu, и это будет post метод.   -  person Saad    schedule 01.08.2020
comment
@Саад, не могли бы вы показать пример?   -  person Jimothy Cardotha    schedule 01.08.2020
comment
@ Atlas435 Не совсем, так как это включает в себя создание меню с помощью tk.Frame, а не tk.Menu, но все равно спасибо.   -  person Jimothy Cardotha    schedule 02.08.2020


Ответы (2)


Вы можете создать что-то подобное из виджетов Tkinter, таких как Frame и Menu. Очень просто мы можем связать post(x, y) метод меню с меткой кнопки, чтобы получить меню по любой (x, y) координате, но здесь мы будем использовать x=root x coordinate of the label и y=root x coordinate of the label + height of the label.

Поскольку я работаю в macOS и у меня нет доступа к компьютеру с Windows, я не смог протестировать его в Windows, но я уверен, что он должен нормально работать в Windows.

Вот пример, а не полная версия. Это поможет вам начать работу, и вы сможете изменить или добавить функции в соответствии с вашими потребностями.

import tkinter as tk


class CustomMenuBar(tk.Frame):
    def __init__(self, master=None, cnf={}, **kw):
        kw = tk._cnfmerge((cnf, kw))
        kw['relief'] = kw.get('relief', 'raised')
        self._fg = kw.pop('fg', kw.pop('foreground', 'black'))
        self._over_bg = kw.pop('overbackground', 'blue')
        super().__init__(master=master, **kw)
        self._lb_list = []
    
    def _on_press(self, label, command=None):
        """Internal function.\n
        This is called when a user clicks on a menubar."""
        label.menu.post(label.winfo_rootx(), 
            label.winfo_rooty() + label.winfo_height() + 5) # 5 padding (set accordingly)
        if command: command()  # Calls the function passed to `add_menu` method.
    
    def add_menu(self, title, menu, command=None):
        """Add menu labels."""
        l = tk.Label(self, text=title, fg=self._fg, bg=self['bg'], padx=2, pady=2)
        l.pack(side='left')
        l.bind('<Enter>', lambda e: l.config(bg=self._over_bg))
        l.bind('<Leave>', lambda e: l.config(bg=self['bg']))
        l.menu = menu  # Easy to access menu with the instance 
                       #   of the label saved in the `self._lb_list`
        l.bind('<1>', lambda e: self._on_press(l, command))
        self._lb_list.append(l)


def demo():
    root = tk.Tk()
    root.geometry('200x200')
    mb = CustomMenuBar(root, bg='black', fg='white', overbackground='#2C41FF')
    mb.pack(side='top', expand=1, fill='x', anchor='n')

    filemenu = tk.Menu(mb)
    filemenu.add_command(label='New')
    filemenu.add_command(label='Open')
    filemenu.add_separator()
    filemenu.add_command(label='Exit', command=root.quit)

    editmenu = tk.Menu(mb)
    editmenu.add_command(label='Copy')
    editmenu.add_command(label='Paste')

    mb.add_menu('File', filemenu)
    mb.add_menu('Edit', editmenu)

    root.mainloop()

if __name__ == "__main__":
    demo()   
person Saad    schedule 01.08.2020

Вы не можете изменить цвет объекта tk.Menu.

person cs1349459    schedule 01.08.2020
comment
Вы можете создать свой собственный класс, но это будет сложно. - person cs1349459; 01.08.2020
comment
@cs1349459: Нет ничего сложного, если ты думаешь, что это сложно, то ты усложняешь, просто думая о том, как это сложно, лол. - person Saad; 01.08.2020
comment
@Саад мне тяжело :( Лель - person Cool Cloud; 01.08.2020