PySimpleGUI - Menubar 菜单栏

大多数桌面应用程序都有一个菜单系统,可以根据用户在菜单中选择的选项触发不同的操作。 在典型的应用程序窗口中,菜单栏位于标题栏的正下方和窗口客户区的上方。

菜单栏是由可点击按钮组成的水平栏。 单击这些按钮中的任何一个时,它会生成一个选项按钮的下拉列表。 这样的选项按钮会触发一个可以在事件循环内处理的点击事件。

菜单系统的设计就像指定窗口布局一样。 它也是列表的列表。 每个列表都有一个或多个字符串。 第一级列表的起始字符串是出现在水平菜单栏中的按钮的标题。 它后面是下拉菜单中选项按钮的标题字符串列表。 这些选项标题位于第一级列表内的列表中。

您可能在选项按钮下有一个子菜单,在这种情况下,标题会放在第三级列表中。 同样,标题可以嵌套到任何层级。

菜单定义的一般格式如下:

menu_def = [
   ['Memu1', ['btn1', 'btn2', 'btn3', 'btn4',]],
   ['menu2', ['btn5', 'btn6','btn7', 'btn8'],],
]

要将菜单系统附加到 PysimpleGUI 窗口的主布局,请将 Menu 对象放在布局的第一行。

Menu 构造函数以 menu_def 列表作为参数。 主布局的其他行可以在具有 Menu 对象的行之后给出。

layout= [[psg.Menu(menu_def),[..], [..]]

在下面给出的代码中,我们有一个包含文件、编辑和帮助菜单的菜单栏,每个菜单栏中都有几个菜单按钮。

import PySimpleGUI as psg
menu_def = [['File', ['New', 'Open', 'Save', 'Exit', ]], ['Edit', ['Cut', 'Copy', 'Paste', 'Undo'], ],  ['Help', 'About...'], ]
layout = [[psg.Menu(menu_def)],
   [psg.Multiline("", key='-IN-',
   expand_x=True, expand_y=True)],
   [psg.Multiline("", key='-OUT-',
   expand_x=True, expand_y=True)],
   [psg.Text("", key='-TXT-',
   expand_x=True, font=("Arial Bold", 14))]
]
window = psg.Window("Menu", layout, size=(715, 300))
while True:
   event, values = window.read()
   print(event, values)

   if event != psg.WIN_CLOSED:
      window['-TXT-'].update(values[0] + "Menu Button Clicked")
   if event == 'Copy':
      txt = window['-IN-'].get()
   if event == 'Paste':
      window['-OUT-'].update(value=txt)
   if event == psg.WIN_CLOSED:
      break
window.close()

在菜单栏下方,放置了两个多行元素。 最后一行有一个文本元素。

单击任何菜单选项按钮时,生成的事件就是按钮的标题。 此标题显示在最后一行的文本标签上。 参考下图 −

菜单栏显示

当Copy事件发生时,上面带有-INkey的多行框中的文本被存储在一个txt变量中。 之后,当按下粘贴按钮时,-OUT- 框将更新为 txt 的值。

菜单栏编辑

带热键的菜单按钮

要将菜单按钮映射到键盘上的某个键,请在所需字符前放置一个 & 字符。 例如,将 & 放在 File 之前,这样字符串就是 '&File'。 通过这样做,可以通过按"Alf+F"键访问"文件"菜单。 这里的"F"键被称为热键。

在我们的菜单定义中为菜单按钮添加热键。

menu_def = [
   ['&File', ['&New', '&Open', '&Save', 'E&xit',]],
   ['&Edit', ['C&ut', '&Copy','&Paste', '&Undo'],],
   ['&Help', '&About...'],
]

运行代码时,菜单中的热键显示为带下划线。

菜单按钮热键

右键菜单

此菜单与应用程序窗口顶部的菜单栏分离。 每当用户按下鼠标右键单击按钮时,此菜单就会在单击发生的同一位置弹出。

在上面定义的菜单栏中,每个列表都是对单个菜单的定义。 这样的单个菜单定义可以通过构造函数中的 right_click_menu 参数附加到任何元素。 这个参数也可以在构造主窗口对象时传递。

让我们使用右键单击作为与编辑菜单对应的列表的变量。

rightclick=['&Edit', ['C&ut', '&Copy','&Paste', '&Undo']]
menu_def = [
   ['&File', ['&New', '&Open', '&Save', 'E&xit',]], rightclick,
   ['&Help', '&About...'],
]

将其用作 Window 构造函数中 right_click_menu 参数的值。 请参阅以下代码段 −

window=psg.Window("Menu", layout, size=(715, 300), right_click_menu=rightclick)

进行这些更改并运行代码。 单击窗口中的任意位置。 弹出菜单如图 −

右键菜单

ButtonMenu 按钮菜单

这个菜单类似于右键菜单,不同之处在于它附加在一个按钮上,并在单击按钮时弹出。

在主布局的最后一行,我们添加了一个 ButtonMenu 元素并使用右键单击列表作为其布局。

layout= [
   [psg.Menu(menu_def)],
   [psg.Multiline("", key='-IN-', expand_x=True, expand_y=True)],
   [psg.Multiline("", key='-OUT-', expand_x=True, expand_y=True)],
   [psg.Text("", key='-TXT-', expand_x=True, font=("Arial Bold", 14)),
   psg.ButtonMenu('ButtonMenu', rightclick, key='-BMENU-')]
]

当点击右下角的按钮时,会出现如下图所示的菜单 −

ButtonMenu 按钮菜单