python - 不使用小部件 tk.Menu 的自定义菜单栏
问题描述
我想个性化一个菜单栏。例如,我想删除出现在 tk.Menu 小部件周围的边框(使用 add_command() 方法)
这是我的代码(我使用的是 Windows 10)
import tkinter as tk
from tkinter import ttk
dark_grey = "#212121"
dark_blue="#102A43"
blue_1="#243B53"
root = tk.Tk()
root.state('zoomed')
container = tk.Frame(root, bg = dark_grey)
container.grid_rowconfigure(0, weight = 0)
container.grid_columnconfigure(0, weight = 1)
menu_frame = tk.Frame(container, bg = dark_blue)
menu1 = tk.Menubutton(menu_frame, text = "Menu1", bg = dark_blue, fg =
"white", activebackground = blue_1, activeforeground =
"white")
menu1.grid(row = 0, column = 0)
submenu1 = tk.Menu(menu1, tearoff = 0, bg = dark_blue,
activebackground= blue_1, fg = "white",borderwidth = 0, activeborderwidth= 0)
submenu1.add_command(label = "Option 1.1")
submenu1.add_command(label = "Option 1.2")
menu1.configure(menu = submenu1)
menu_frame.grid(row = 0, column = 0, sticky = "ew")
container.pack(fill = tk.BOTH, expand = "True")
root.mainloop()
我的想法是在不使用 tk.Menu 和 tk.MenuButton 的情况下创建一个菜单。我想将<Enter>
事件“绑定”到标签,以便在标签下创建一种下拉菜单。可能吗?
解决方案
问题:不使用小部件的自定义菜单栏
tk.Menu
?
此示例使用 atk.Toplevel
作为弹出窗口并显示添加的tk.Menubutton
. 子菜单遵循顶部
定义
的样式。 tk.Menubutton
待办事项:
- 如果在外部或另一个Top
Menubutton
中单击,则关闭弹出窗口。- 以其他方式扩展
tk.Menubutton
- 键盘支持
import tkinter as tk
class Menu:
def __init__(self, parent, **kwargs):
self._popup = None
self._menubutton = []
self.parent = parent
self.parent.bind('<Button-1>', self.on_popup)
def on_popup(self, event):
w = event.widget
x, y, height = self.parent.winfo_rootx(), self.parent.winfo_rooty(), self.parent.winfo_height()
self._popup = tk.Toplevel(self.parent.master, bg=self.parent.cget('bg'))
self._popup.overrideredirect(True)
self._popup.geometry('+{}+{}'.format(x, y + height))
for kwargs in self._menubutton:
self._add_command(**kwargs)
def add_command(self, **kwargs):
self._menubutton.append(kwargs)
def _add_command(self, **kwargs):
command = kwargs.pop('command', None)
menu = self.parent
mb = tk.Menubutton(self._popup, text=kwargs['label'],
bg=menu.cget('bg'),
fg=menu.cget('fg'),
activebackground=menu.cget('activebackground'),
activeforeground=menu.cget('activeforeground'),
borderwidth=0,
)
mb._command = command
mb.bind('<Button-1>', self._on_command)
mb.grid()
def _on_command(self, event):
w = event.widget
print('_on_command("{}")'.format(w.cget('text')))
self._popup.destroy()
if w._command is not None:
w._command()
用法:
class App(tk.Tk):
def __init__(self):
super().__init__()
self.geometry("200x200")
style = {'bg': "#102A43", 'fg': "white",
'activebackground': "#243B53", 'activeforeground': "white",
'borderwidth': 0}
menu1 = tk.Menubutton(self, text="Menu1", **style)
submenu1 = Menu(menu1)
submenu1.add_command(label="Option 1.1")
submenu1.add_command(label="Option 1.2")
menu1.grid(row=0, column=0)
menu2 = tk.Menubutton(self, text="Menu2", **style)
submenu2 = Menu(menu2)
submenu2.add_command(label="Option 2.1")
submenu2.add_command(label="Option 2.2")
menu2.grid(row=0, column=2)
if __name__ == "__main__":
App().mainloop()
用 Python 测试:3.5 - 'TclVersion':8.6 'TkVersion':8.6
推荐阅读
- reactjs - Jotai + React:意外的重新渲染和意外的陈旧状态值
- html - 当我将边栏中的内容设置为显示时,它不再随浏览器窗口一起缩小:grid
- java - 控制台整体执行程序的问题
- c++ - for 循环条件 (str1[i] && str2[i]) 是什么意思?
- jenkins - 在 Clearcase 中使用 Jenkins 创建分支和配置文件
- javascript - 使用组件反应 Typescript 自动完成
- rxjs - 关于 2 个 rxjs 可观察对象和一个计时器的问题
- xcode - Xcode lldb 无法附加到 MacOS 系统程序 /bin/cp -“不允许附加到进程。”
- testing - 有没有办法测试 roblox 游戏?
- python - 在python顶部水平对齐图例