不使用小部件 tk.Menu 的自定义菜单栏 [英] A customized menu bar without using the widget tk.Menu

查看:22
本文介绍了不使用小部件 tk.Menu 的自定义菜单栏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想个性化一个菜单栏.例如,我想删除 tk.Menu 小部件周围出现的边框(使用 add_command() 方法)

这是我的代码(我使用的是 Windows 10)

将 tkinter 导入为 tk从 tkinter 导入 ttkdark_grey = "#212121"dark_blue="#102A43"blue_1="#243B53"根 = tk.Tk()root.state('放大')容器 = tk.Frame(root, bg = dark_grey)container.grid_rowconfigure(0, weight = 0)container.grid_columnconfigure(0, weight = 1)menu_frame = tk.Frame(容器,bg = dark_blue)menu1 = tk.Menubutton(menu_frame, text = "Menu1", bg = dark_blue, fg =白色",activebackground = blue_1,activeforeground =白色的")menu1.grid(行 = 0,列 = 0)submenu1 = tk.Menu(menu1, 撕下 = 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 的情况下创建菜单.我想将 事件绑定"到标签,以便在标签下创建一种下拉菜单.可能吗?

解决方案

问题:不使用小部件tk.Menu的自定义菜单栏?

此示例使用 tk.Toplevel 作为弹出窗口并显示添加的 tk.Menubutton.
Submenu 遵循 Top tk.Menubutton 的定义样式.

<小时><块引用>

待办事项:

  • 如果点击外部或另一个顶部,则关闭弹出窗口Menubutton.
  • 扩展不只是tk.Menubutton
  • 键盘支持

<小时>

将 tkinter 导入为 tk班级菜单:def __init__(self, parent, **kwargs):self._popup = 无self._menubutton = []self.parent = 父母self.parent.bind('', self.on_popup)def on_popup(self, event):w = event.widgetx, y, 高度 = 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(真)self._popup.geometry('+{}+{}'.format(x, y + height))对于 self._menubutton 中的 kwargs:self._add_command(**kwargs)def add_command(self, **kwargs):self._menubutton.append(kwargs)def _add_command(self, **kwargs):command = kwargs.pop('command', None)菜单 = self.parentmb = tk.Menubutton(self._popup, text=kwargs['label'],bg=menu.cget('bg'),fg=menu.cget('fg'),activebackground=menu.cget('activebackground'),activeforeground=menu.cget('activeforeground'),边框宽度=0,)mb._command = 命令mb.bind('', self._on_command)mb.grid()def _on_command(self, event):w = event.widgetprint('_on_command("{}")'.format(w.cget('text')))self._popup.destroy()如果 w._command 不是 None:w._command()

<块引用>

用法:

类应用程序(tk.Tk):def __init__(self):super().__init__()self.geometry("200x200")style = {'bg': "#102A43", 'fg': "white",'activebackground': "#243B53", 'activeforeground': "white",'边界宽度':0}menu1 = tk.Menubutton(self, text="Menu1", **style)子菜单 1 = 菜单(菜单 1)submenu1.add_command(label="Option 1.1")submenu1.add_command(label="Option 1.2")menu1.grid(行=0,列=0)menu2 = tk.Menubutton(self, text="Menu2", **style)子菜单 2 = 菜单(菜单 2)submenu2.add_command(label="Option 2.1")submenu2.add_command(label="Option 2.2")menu2.grid(行=0,列=2)如果 __name__ == "__main__":应用程序().主循环()

使用 Python 测试:3.5 - 'TclVersion':8.6 'TkVersion':8.6

I would like to personalized a menu bar. For example I want to delete the border that appears around the tk.Menu widget (with the add_command() method)

That's my code (I'm using 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()

My idea is to create a menu without using tk.Menu and tk.MenuButton. I would like "bind" an <Enter> event to a label, in order to create a sort of drop down under the label. Is it possible?

解决方案

Question: Customized menu bar without using the widget tk.Menu?

This example uses a tk.Toplevel as a popup window and displays the added tk.Menubutton.
The Submenu follows ths defined Style of the Top tk.Menubutton.


TODO:

  • Close the Popup Window if clicked outside or another Top Menubutton.
  • Extend with other than only tk.Menubutton
  • Keyboard support


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

Usage:

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

Tested with Python: 3.5 - 'TclVersion': 8.6 'TkVersion': 8.6

这篇关于不使用小部件 tk.Menu 的自定义菜单栏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆