前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python GuiMaker 菜单封装 工具

python GuiMaker 菜单封装 工具

作者头像
用户5760343
发布2022-05-13 10:47:48
5210
发布2022-05-13 10:47:48
举报
文章被收录于专栏:sktj

""" ############################################################################### An extended Frame that makes window menus and toolbars automatically. Use GuiMakerFrameMenu for embedded components (makes frame-based menus). Use GuiMakerWindowMenu for top-level windows (makes Tk8.0 window menus). See the self-test code (and PyEdit) for an example layout tree format. ############################################################################### """

import sys from tkinter import * # widget classes from tkinter.messagebox import showinfo

class GuiMaker(Frame): menuBar = [] # class defaults toolBar = [] # change per instance in subclasses helpButton = True # set these in start() if need self

代码语言:javascript
复制
def __init__(self, parent=None):
    Frame.__init__(self, parent)
    self.pack(expand=YES, fill=BOTH)        # make frame stretchable
    self.start()                            # for subclass: set menu/toolBar
    self.makeMenuBar()                      # done here: build menu bar
    self.makeToolBar()                      # done here: build toolbar
    self.makeWidgets()                      # for subclass: add middle part

def makeMenuBar(self):
    """
    make menu bar at the top (Tk8.0 menus below)
    expand=no, fill=x so same width on resize
    """
    menubar = Frame(self, relief=RAISED, bd=2)
    menubar.pack(side=TOP, fill=X)

    for (name, key, items) in self.menuBar:
        mbutton  = Menubutton(menubar, text=name, underline=key)
        mbutton.pack(side=LEFT)
        pulldown = Menu(mbutton)
        self.addMenuItems(pulldown, items)
        mbutton.config(menu=pulldown)

    if self.helpButton:
        Button(menubar, text    = 'Help',
                        cursor  = 'gumby',
                        relief  = FLAT,
                        command = self.help).pack(side=RIGHT)

def addMenuItems(self, menu, items):
    for item in items:                     # scan nested items list
        if item == 'separator':            # string: add separator
            menu.add_separator({})
        elif type(item) == list:           # list: disabled item list
            for num in item:
                menu.entryconfig(num, state=DISABLED)
        elif type(item[2]) != list:
            menu.add_command(label     = item[0],         # command:
                             underline = item[1],         # add command
                             command   = item[2])         # cmd=callable
        else:
            pullover = Menu(menu)
            self.addMenuItems(pullover, item[2])          # sublist:
            menu.add_cascade(label     = item[0],         # make submenu
                             underline = item[1],         # add cascade
                             menu      = pullover)

def makeToolBar(self):
    """
    make button bar at bottom, if any
    expand=no, fill=x so same width on resize
    this could support images too: see Chapter 9,
    would need prebuilt gifs or PIL for thumbnails
    """
    if self.toolBar:
        toolbar = Frame(self, cursor='hand2', relief=SUNKEN, bd=2)
        toolbar.pack(side=BOTTOM, fill=X)
        for (name, action, where) in self.toolBar:
            Button(toolbar, text=name, command=action).pack(where)

def makeWidgets(self):
    """
    make 'middle' part last, so menu/toolbar
    is always on top/bottom and clipped last;
    override this default, pack middle any side;
    for grid: grid middle part in a packed frame
    """
    name = Label(self,
                 width=40, height=10,
                 relief=SUNKEN, bg='white',
                 text   = self.__class__.__name__,
                 cursor = 'crosshair')
    name.pack(expand=YES, fill=BOTH, side=TOP)

def help(self):
    "override me in subclass"
    showinfo('Help', 'Sorry, no help for ' + self.__class__.__name__)

def start(self):
    "override me in subclass: set menu/toolbar with self"
    pass

###############################################################################

Customize for Tk 8.0 main window menu bar, instead of a frame

###############################################################################

GuiMakerFrameMenu = GuiMaker # use this for embedded component menus

class GuiMakerWindowMenu(GuiMaker): # use this for top-level window menus def makeMenuBar(self): menubar = Menu(self.master) self.master.config(menu=menubar)

代码语言:javascript
复制
    for (name, key, items) in self.menuBar:
        pulldown = Menu(menubar)
        self.addMenuItems(pulldown, items)
        menubar.add_cascade(label=name, underline=key, menu=pulldown)

    if self.helpButton:
        if sys.platform[:3] == 'win':
            menubar.add_command(label='Help', command=self.help)
        else:
            pulldown = Menu(menubar)  # Linux needs real pull down
            pulldown.add_command(label='About', command=self.help)
            menubar.add_cascade(label='Help', menu=pulldown)

###############################################################################

Self-test when file run standalone: 'python guimaker.py'

###############################################################################

if name == 'main': from guimixin import GuiMixin # mix in a help method

代码语言:javascript
复制
menuBar = [
    ('File', 0,
        [('Open',  0, lambda:0),         # lambda:0 is a no-op
         ('Quit',  0, sys.exit)]),       # use sys, no self here
    ('Edit', 0,
        [('Cut',   0, lambda:0),
         ('Paste', 0, lambda:0)]) ]
toolBar = [('Quit', sys.exit, {'side': LEFT})]

class TestAppFrameMenu(GuiMixin, GuiMakerFrameMenu):
    def start(self):
        self.menuBar = menuBar
        self.toolBar = toolBar

class TestAppWindowMenu(GuiMixin, GuiMakerWindowMenu):
    def start(self):
        self.menuBar = menuBar
        self.toolBar = toolBar

class TestAppWindowMenuBasic(GuiMakerWindowMenu):
    def start(self):
        self.menuBar = menuBar
        self.toolBar = toolBar    # guimaker help, not guimixin

root = Tk()
TestAppFrameMenu(Toplevel())
TestAppWindowMenu(Toplevel())
TestAppWindowMenuBasic(root)
root.mainloop()

///guimaker 和guimixin 使用例子 """ GUI demo implementation - combines maker, mixin, and this """

import sys, os from tkinter import * # widget classes from PP4E.Gui.Tools.guimixin import * # mix-in methods: quit, spawn, etc. from PP4E.Gui.Tools.guimaker import * # frame, plus menu/toolbar builder

class Hello(GuiMixin, GuiMakerWindowMenu): # or GuiMakerFrameMenu def start(self): self.hellos = 0 self.master.title("GuiMaker Demo") self.master.iconname("GuiMaker") def spawnme(): self.spawn('big_gui.py') # defer call vs lambda

代码语言:javascript
复制
    self.menuBar = [                               # a tree: 3 pull downs
      ('File', 0,                                  # (pull-down)
          [('New...',  0, spawnme), 
           ('Open...', 0, self.fileOpen),          # [menu items list]
           ('Quit',    0, self.quit)]              # label,underline,action
      ),

      ('Edit', 0,
          [('Cut',    -1, self.notdone),           # no underline|action
           ('Paste',  -1, self.notdone),           # lambda:0 works too
           'separator',                            # add a separator
           ('Stuff',  -1,
               [('Clone', -1, self.clone),         # cascaded submenu
                ('More',  -1, self.more)]
           ),
           ('Delete', -1, lambda:0),
           [5]]                                    # disable 'delete'
      ),

      ('Play', 0,
          [('Hello',     0, self.greeting),
           ('Popup...',  0, self.dialog),
           ('Demos',     0,
              [('Toplevels', 0,
                   lambda: self.spawn(r'..\Tour\toplevel2.py')),
               ('Frames',    0,
                   lambda: self.spawn(r'..\Tour\demoAll-frm-ridge.py')),
               ('Images',    0,
                   lambda: self.spawn(r'..\Tour\buttonpics.py')),
               ('Alarm',     0,
                   lambda: self.spawn(r'..\Tour\alarm.py', wait=False)),
               ('Other...', -1, self.pickDemo)]
           )]
      )]

    self.toolBar = [                                     # add 3 buttons
      ('Quit',  self.quit,     dict(side=RIGHT)),        # or {'side': RIGHT}
      ('Hello', self.greeting, dict(side=LEFT)), 
      ('Popup', self.dialog,   dict(side=LEFT, expand=YES)) ]

def makeWidgets(self):                                   # override default
    middle = Label(self, text='Hello maker world!',      # middle of window 
                   width=40, height=10, 
                   relief=SUNKEN, cursor='pencil', bg='white')
    middle.pack(expand=YES, fill=BOTH)

def greeting(self):
    self.hellos += 1
    if self.hellos % 3:
        print("hi")
    else:
        self.infobox("Three", 'HELLO!')    # on every third press

def dialog(self):
    button = self.question('OOPS!',
                           'You typed "rm*" ... continue?',  # old style
                           'questhead', ('yes', 'no'))       # args ignored
    [lambda: None, self.quit][button]()

def fileOpen(self):
    pick = self.selectOpenFile(file='big_gui.py')
    if pick:
        self.browser(pick)     # browse my source file, or other

def more(self):
    new = Toplevel()
    Label(new,  text='A new non-modal window').pack()
    Button(new, text='Quit', command=self.quit).pack(side=LEFT)
    Button(new, text='More', command=self.more).pack(side=RIGHT)

def pickDemo(self):
    pick = self.selectOpenFile(dir='..')
    if pick:
        self.spawn(pick)    # spawn any Python program

if name == 'main': Hello().mainloop() # make one, run one

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Customize for Tk 8.0 main window menu bar, instead of a frame
  • Self-test when file run standalone: 'python guimaker.py'
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档