2.1 设计GUI之PySimpleGUI的基础教程

学习资源:Trinket: PySimpleGUI Program

PySimpleGUI 是一个十分 Pythonic 的 GUI 框架。为了叙述方便将 PySimpleGUI 简记为 sg,窗口(Window)主题有超过 100 个可供选择,您可以使用函数 sg.preview_all_look_and_feel_themes() 查看所有主题。切换主题需要使用回调函数 sg.change_look_and_feel("主题名称")

import PySimpleGUI as sg

# 变换主题
sg.change_look_and_feel('Material1')

下面将讨论 PySimpleGUI 的几个核心组件,虽然每个组件的参数可能很多,但是我们只需要了解其核心参数即可,所以,下面的介绍仅仅列出函数的核心参数,比如像 sg.Window(title, layout, size=(5, 1)) 这种形式。

1 sg.Popup 设计 I/O

sg.Popupprint 相当(用于输出(Output)),它创建了一个支持任意数量的任意 Python 支持的数据类型作为参数输入的 Window。变体有:sg.PopupOKsg.PopupOKCancelsg.PopupCancelsg.PopupErrorsg.PopupAutoClosesg.PopupYesNosg.PopupTimed

关于输入(Input)可以使用 sg.PopupGetTextsg.PopupGetFilesg.PopupGetFolder 获取用户的文本,文件,文件夹输入。

2 sg.Window 创建窗口

GUI 的设计目标一般都需要有一个用于和用户进行交互的窗口(Window)界面,为此 PySimpleGUI 提供 sg.Window 类创建窗口。使用方法:sg.Window(title, layout) ,其中 title 表示窗口的标题,layout 指定窗口的布局。

图1 一个简单的 Window 布局

图1 提供了一个自定义 Window 布局以及如何使用其与用户交互的例子。下面对图1 的代码进行拆解。第 7~9 行定义了 Window 的布局,第 12 行定义了一个 Window,第 14~23 行定义了 Window 的交互方法,第 24 行将 Window 关闭以释放资源。其中 sg.Textsg.T == sg.Text == sg.Txt)会将字符串打印到 Window,sg.Inputsg.I == sg.InputText == sg.Input == sg.In)用于获取用户的输入,sg.Button(sg.B == sg.Button)表示 Window 的按钮。下面看看 Window.Read 的输出:

图2 测试 Window.Read 的输出

从图2 可以看出 values 是关键字为数字序号的 dict,而 event 一般代表 Window 的按钮。然而,若 Window 中的 sg.Input 很多,我们仅仅依靠数字序号将十分不方便,为此我们需要传入 key 修改 dict 的关键字。具体实现见图3。

图3 修改 sg.In 的关键字

接下来您便可以使用关键字获取对应的表单数据。

3 在窗口显示用户输入

窗口 sg.Window 的元素可以通过类似于 dict 的方式进行更新及获取:

图4 在窗口显示用户输入

图4 显示了 sg.Window元素(也可称为“小部件”,“组件”)可以通过关键字(即 -OUTPUT-)获取,使用 update 方法更新。

这里的sg.Window元素,即:

IN = window['-IN-']
IN

显示为:


获取该元素的值:

IN.get()

显示结果为:

'平安是福'

4 创建 To Do List

下面我们创建 To Do 表单:

图5 创建 To Do List

图5 中 出现了复选项 sg.CBox,它的返回值是 True 或者 False,而 window.save_to_disk('ToDoList.out') 将 Window 的配置保存在磁盘,window.load_from_disk('ToDoList.out') 载入磁盘保存的 Window 配置。

5 创建菜单栏

先上代码:

import PySimpleGUI as sg

# ------ Menu Definition ------ #
menu_def = [['&File', ['&Open', '&Save', 'E&xit', 'Properties']],
            ['&Edit', ['Paste', ['Special', 'Normal', ], 'Undo'], ],
            ['&Help', '&About...']]

relief_list = [sg.RELIEF_RAISED, sg.RELIEF_SUNKEN, sg.RELIEF_FLAT, 
               sg.RELIEF_RIDGE, sg.RELIEF_GROOVE, sg.RELIEF_SOLID]

def layout_relief(element):
    return sg.Text(element,
                   size=(30, 1), justification='center', 
                   font=("Helvetica", 25), relief=element)
    

layout = [[sg.Menu(menu_def, tearoff=True)]]
layout += [[layout_relief(element)] for element in relief_list]

window = sg.Window('Everything bagel', layout, default_element_size=(40, 1), grab_anywhere=False)
event, values = window.read()
window.close()

menu_def 定义了多级菜单栏,relief_list 展示了文本显示的样式,sg.Text 的参数 size=(30, 1) 表示文本框是宽30个字符,高1个字符。具体效果见图6:

图6 创建多级菜单栏

6 方法名称简写

  1. 下拉列表:Combo == InputCombo == DropDown == Drop
  2. 文本输入:InputText == Input == In
  3. 复选框:CBox == CB == Check
  4. 按钮:Button== ReadButton == RButton == ReadFormButton
  5. 多行文本框:Multiline == MLine

7 “选择器” 按钮

“选择器” 按钮("Chooser" Buttons)会弹出一个对话框用于选择 filename, date, color 等等。这些按钮直接可以通过名称便可以知道其代表的含义,即 FileBrowse, FolderBrowse, FileSaveAs , FilesSaveAs, CalendarButton, ColorChooserButton。比如使用 FolderBrowse 打开文件夹并将文件夹名称传递给 sg.In,效果图见图7:

图7 打开文件夹并将文件夹名称传递给 `sg.In`

也可以自定义按钮:layout = [[sg.Button('My Button', key='_BUTTON_KEY_')]]

8 其他方法简介

  1. Listbox 示例:layout = [[sg.Listbox(values=['Listbox 1', 'Listbox 2', 'Listbox 3'], size=(30, 6))]],效果见图8:
图8 Listbox + 带表头的表格
  1. 多行文本输入输出:sg.Multiline,效果见图9:
图9 多行输入输出
  1. Slider(滑动条)sg.Slider,效果见图10:
图10 滑块
  1. 单选 sg.Radio 与多选 sg.Checkbox,具体效果见图11:
图11 单选与复选项

需要注意的是 sg.Radio 的第2个参数是用来标识此选项是否归属于指定的 ID

  1. 上/下微调控件(An up/down spinner control)sg.Spin,效果图见图12:
图12 上/下微调控件
  1. Progress Meter
import PySimpleGUI as sg

# layout the window
layout = [[sg.Text('A custom progress meter')],
          [sg.ProgressBar(1000, orientation='h', size=(20, 20), key='progressbar')],
          [sg.Cancel()]]

# create the window`
window = sg.Window('Custom Progress Meter', layout)
progress_bar = window['progressbar']
# loop that would normally do something useful
for i in range(1000):
    # check to see if the cancel button was clicked and exit loop if clicked
    event, values = window.read(timeout=10)
    if event in ['Cancel', None]:
        break
  # update bar with loop value +1 so that bar eventually reaches the maximum
    progress_bar.UpdateBar(i + 1)
# done with loop... need to destroy the window as it's still open
window.close()

效果图见图13:

图13 进度条

7 Column

import PySimpleGUI as sg

# Demo of how columns work
# window has on row 1 a vertical slider followed by a COLUMN with 7 rows
# Prior to the Column element, this layout was not possible
# Columns layouts look identical to window layouts, they are a list of lists of elements.

window = sg.Window('Columns')                                   # blank window

# Column layout
col = [[sg.Text('col Row 1')],
       [sg.Text('col Row 2'), sg.Input('col input 1')],
       [sg.Text('col Row 3'), sg.Input('col input 2')],
       [sg.Text('col Row 4'), sg.Input('col input 3')],
       [sg.Text('col Row 5'), sg.Input('col input 4')],
       [sg.Text('col Row 6'), sg.Input('col input 5')],
       [sg.Text('col Row 7'), sg.Input('col input 6')]]

layout = [[sg.Slider(range=(1,100), default_value=10, 
             orientation='v', size=(8,20)), sg.Column(col)],
          [sg.In('Last input')],
          [sg.OK()]]

# Display the window and get values

window = sg.Window('Compact 1-line window with column', layout)
event, values = window.read()
window.Close()

sg.Popup(event, values, line_width=200)

显示效果见图14:

图14 数据列
  1. 运行 sg.main() 有惊喜,截图见图15:
图15 sg.main
  1. 创建一个控制面板(资料来源:)

代码(图片被转换为了Base64字符):

import PySimpleGUI as sg

"""
    Creates a grid of buttons include of a column for scrolling
    This window looks much like a control panel
    
    NOTE - The SCROLLING using the mousewheel is known to have a bug in the tkinter port.  You will need to have your mouse over the scrollbar to scroll with the mousewheel
"""

def GraphicButton(text:str, key:str, image_data):
    text = text.replace('_', ' ')
    button = sg.Button('', image_data=image_data, button_color=('white', '#9FB8AD'), font='Any 15', key=key, border_width=0)
    text = sg.Text(text, font='Any 10', size=(15,1), justification='center',)
    return sg.Column([[button],[text]], element_justification='c')

def main():
    sg.ChangeLookAndFeel('GreenTan')

    layout  = [ [sg.Text('Control Panel. Click Abort to exit.')]]
    layout += [[sg.Column([[GraphicButton(png_names[i+j*5], png_names[i+j*5] , png_images[i+j*5]) for i in range(2)] for j in range(7)], scrollable=True, size=(400,400))]]

    window = sg.Window('Control Panel', layout, font='any 15', finalize=True)
    while True:                               # ---===--- The event loop --- #
        event, values = window.read()
        print(event)
        if event in ('Exit','Abort', None):   # Exit button or X
            break
    window.close()


Abort = b"..."
...
vars = dir()
png_images = []
png_names = []
for var in vars:
    png_images.append(eval(var))
    png_names.append(var)

main()

显示效果图见图16:

图16 控制面板

你可能感兴趣的:(2.1 设计GUI之PySimpleGUI的基础教程)