探索PySimpleGUI:一款简洁易用的图形用户界面库

简介: 探索PySimpleGUI:一款简洁易用的图形用户界面库

PySimpleGUI

PySimpleGUI是一个基于Tkinter、WxPython、Qt等底层库构建的图形界面框架,其设计目标是使Python GUI编程变得更加简单直观,大大降低了入门门槛。无论是初学者还是经验丰富的开发者,都可以快速上手并高效地创建出功能丰富、外观现代的桌面应用程序。

PySimpleGUI的核心优势在于其高度抽象化的API设计,它提供了包括按钮、输入框、列表框、滑块等各种常见的GUI元素。除了基本的布局和样式设置,PySimpleGUI还支持事件驱动的编程模型。你可以为元素添加事件处理程序,以便响应用户与窗口的交互,如点击按钮、选择菜单项等。事件处理程序可以根据需要执行各种操作,如更新元素的值、触发其他事件或执行自定义代码。

此外,PySimpleGUI还提供了许多有用的功能和工具,如表单验证、动画和动画效果、工具提示等,这些功能可以帮助你构建更丰富和交互式的GUI应用程序;其次,PySimpleGUI还支持自定义主题,满足不同场景下的UI风格需求;同时,它也具备良好的跨平台兼容性,能够在Windows、Mac和Linux系统下稳定运行。

安装使用

PySimpleGUI 当前版本为 4.60.5,安装命令如下:

C:\> pip install PySimpleGUI

如果你还在用python2.7,那么需要安装对应的库PySimpleGUI27:

C:\> pip install PySimpleGUI27

使用时,一般都PySimpleGUI把导入成别名sg:

importPySimpleGUIassg

代码框架

如创建上面这样一个简单的windows窗口,共布局两个文本框(标签)、一个输入框和两个按钮,其代码的框架分5个部分:

导入库包、控件布局、创建窗口、事件循环、退出窗口

完整代码如下:

import PySimpleGUI as sg  #导入库包
# 定义布局
layout = [
    [sg.Text("请输入你的名字:")],
    [sg.Input(key="-NAME-", enable_events=True)],
    [sg.Button("确定"), sg.Button("退出")],
    [sg.Text(size=(40, 1), key="-OUTPUT-")]
]
# 创建窗口
window = sg.Window("程序标题", layout)
# 事件循环
while True:  
    event, values = window.read()
    if event == "退出" or event == sg.WIN_CLOSED:  
        break  
    elif event == "确定":  
        name = values["-NAME-"]  
        window["-OUTPUT-"].update(f"你好,{name}!")  
#退出窗口
window.close()

导入、创建、退出三步都是固定的,主要学习控件布局和事件循环

常用控件

Text、Input、Button是三种最常见的控件:

Text

是一个用于显示静态文本的控件,在图形用户界面中对用户是不可编辑的信息展示区域。

Text(text='', size=(None, None), s=(None, None), auto_size_text=None, click_submits=False, enable_events=False, relief=None, font=None, text_color=None, background_color=None, border_width=None, justification=None, pad=None, p=None, key=None, k=None, right_click_menu=None, expand_x=False, expand_y=False, grab=None, tooltip=None, visible=True, metadata=None)

主要参数说明:

  • key(str):控件的唯一标识符,用于识别和处理事件。
  • size(tuple):指定控件的大小,格式为 (宽度, 高度)。默认值为 (None, None),表示自动调整大小以适应内容。
  • text(str):要在控件中显示的初始文本内容。默认值为空字符串。
  • disabled(bool):指定控件是否禁用。默认值为 False,表示启用控件。
  • enable_events(bool):指定是否启用控件的事件处理功能。默认值为 True,表示启用事件处理。
  • font(Font):指定控件的字体样式。默认值为 None,表示使用系统默认字体。
  • justification(str):指定文本对齐方式。可选值包括 "left"、"right"、"center" 和 "justify"。默认值为 "left"。
  • expand(bool):指定是否扩展控件以填充其父容器的剩余空间。默认值为 False。
  • pad(int or tuple):指定控件周围的内边距大小。可以是单个整数或包含四个整数的元组,分别代表上、下、左、右边距。默认值为 (0, 0, 0, 0)。
  • background_color(Color):指定控件的背景颜色。默认值为 None,表示使用父容器的背景颜色。
  • border_width(int or tuple):指定控件边框的宽度。可以是单个整数或包含四个整数的元组,分别代表上、下、左、右边框的宽度。默认值为 (2, 2, 2, 2)。
  • border_color(Color):指定控件边框的颜色。默认值为 None,表示使用父容器的边框颜色。
  • readonly(bool):指定控件是否只读。默认值为 False,表示允许编辑文本内容。
  • return_keyboard_events(bool):指定是否返回键盘事件给父窗口。默认值为 True,表示返回键盘事件给父窗口。
  • visible(bool):指定控件是否可见。默认值为 True,表示显示控件。
  • tooltip(str):指定当鼠标悬停在控件上时显示的工具提示文本。默认值为 None,表示不显示工具提示文本。
  • metadata(dict):附加的元数据信息,可以用于自定义属性或行为。默认值为 {},表示没有附加的元数据信息。

Input

也可以写成sg.InputText,Input和InputText是同一个控件。用于在窗口中获取用户输入的文本,也可以接受一个字符串参数作为要显示的初始文本内容。

Input(default_text='', size=(None, None), s=(None, None), disabled=False, password_char='', justification=None, background_color=None, text_color=None, font=None, tooltip=None, border_width=None, change_submits=False, enable_events=False, do_not_clear=True, key=None, k=None, focus=False, pad=None, p=None, use_readonly_for_disable=True, readonly=False, disabled_readonly_background_color=None, disabled_readonly_text_color=None, expand_x=False, expand_y=False, right_click_menu=None, visible=True, metadata=None)

主要参数说明:

  • key(str):控件的唯一标识符,用于识别和处理事件。
  • size(tuple):指定控件的大小,格式为 (宽度, 高度)。默认值为 (None, None),表示自动调整大小以适应内容。
  • default_text(str):要在控件中显示的初始文本内容。默认值为空字符串。
  • disabled(bool):指定控件是否禁用。默认值为 False,表示启用控件。
  • enable_events(bool):指定是否启用控件的事件处理功能。默认值为 True,表示启用事件处理。
  • font(Font):指定控件的字体样式。默认值为 None,表示使用系统默认字体。
  • justification(str):指定文本对齐方式。可选值包括 "left"、"right"、"center" 和 "justify"。默认值为 "left"。
  • expand(bool):指定是否扩展控件以填充其父容器的剩余空间。默认值为 False。
  • pad(int or tuple):指定控件周围的内边距大小。可以是单个整数或包含四个整数的元组,分别代表上、下、左、右边距。默认值为 (0, 0, 0, 0)。
  • background_color(Color):指定控件的背景颜色。默认值为 None,表示使用父容器的背景颜色。
  • border_width(int or tuple):指定控件边框的宽度。可以是单个整数或包含四个整数的元组,分别代表上、下、左、右边框的宽度。默认值为 (2, 2, 2, 2)。
  • border_color(Color):指定控件边框的颜色。默认值为 None,表示使用父容器的边框颜色。
  • readonly(bool):指定控件是否只读。默认值为 False,表示允许编辑文本内容。
  • return_keyboard_events(bool):指定是否返回键盘事件给父窗口。默认值为 True,表示返回键盘事件给父窗口。
  • visible(bool):指定控件是否可见。默认值为 True,表示显示控件。
  • tooltip(str):指定当鼠标悬停在控件上时显示的工具提示文本。默认值为 None,表示不显示工具提示文本。
  • metadata(dict):附加的元数据信息,可以用于自定义属性或行为。默认值为 {},表示没有附加的元数据信息。

Button

也可以写成sg.InputText,Input和InputText是同一个控件。用于在窗口中获取用户输入的文本,也可以接受一个字符串参数作为要显示的初始文本内容。

Button(button_text='', button_type=7, target=(None, None), tooltip=None, file_types=(('ALL Files', '*.* *'),), initial_folder=None, default_extension='', disabled=False, change_submits=False, enable_events=False, image_filename=None, image_data=None, image_size=(None, None), image_subsample=None, image_source=None, border_width=None, size=(None, None), s=(None, None), auto_size_button=None, button_color=None, disabled_button_color=None, highlight_colors=None, mouseover_colors=(None, None), use_ttk_buttons=None, font=None, bind_return_key=False, focus=False, pad=None, p=None, key=None, k=None, right_click_menu=None, expand_x=False, expand_y=False, visible=True, metadata=None)

主要参数说明:

  • key(str):控件的唯一标识符,用于识别和处理事件。
  • size(tuple):指定控件的大小,格式为 (宽度, 高度)。默认值为 (None, None),表示自动调整大小以适应内容。
  • text(str):要在控件上显示的文本内容。默认值为空字符串。
  • disabled(bool):指定控件是否禁用。默认值为 False,表示启用控件。
  • enable_events(bool):指定是否启用控件的事件处理功能。默认值为 True,表示启用事件处理。
  • font(Font):指定控件的字体样式。默认值为 None,表示使用系统默认字体。
  • justification(str):指定文本对齐方式。可选值包括 "left"、"right"、"center" 和 "justify"。默认值为 "left"。
  • expand(bool):指定是否扩展控件以填充其父容器的剩余空间。默认值为 False。
  • pad(int or tuple):指定控件周围的内边距大小。可以是单个整数或包含四个整数的元组,分别代表上、下、左、右边距。默认值为 (0, 0, 0, 0)。
  • background_color(Color):指定控件的背景颜色。默认值为 None,表示使用父容器的背景颜色。
  • border_width(int or tuple):指定控件边框的宽度。可以是单个整数或包含四个整数的元组,分别代表上、下、左、右边框的宽度。默认值为 (2, 2, 2, 2)。
  • border_color(Color):指定控件边框的颜色。默认值为 None,表示使用父容器的边框颜色。
  • readonly(bool):指定控件是否只读。默认值为 False,表示允许编辑文本内容。
  • return_keyboard_events(bool):指定是否返回键盘事件给父窗口。默认值为 True,表示返回键盘事件给父窗口。
  • visible(bool):指定控件是否可见。默认值为 True,表示显示控件。
  • tooltip(str):指定当鼠标悬停在控件上时显示的工具提示文本。默认值为 None,表示不显示工具提示文本。
  • metadata(dict):附加的元数据信息,可以用于自定义属性或行为。默认值为 {},表示没有附加的元数据信息。

布局方法

用一个二维列表(layout)作为 sg.Windows() 的一个参数来创建。

layout = [  [sg.Text('Some text on Row 1')],

           [sg.Text('Enter something on Row 2'), sg.InputText()],

           [sg.Button('Ok'), sg.Button('Cancel')] ]

window = sg.Window('Window Title', layout)

二维列表中还可以用推导式来表达多个控件,比如连续5个按钮:

layout = [[sg.Button(f'按钮{i+1}') for i in range(6)]]

事件循环

标准格式:

while True:

   event, values = window.read()

   if event == sg.WIN_CLOSED or event == '退出':

       break

   elif event.startswith('按钮'):

       print(f'你点击了{event}')

退出事件 sg.WIN_CLOSED 即点了窗口右上角的X关闭钮,event == '退出' 表示点退出按钮。

也可以写成:

if event in (sg.WIN_CLOSED, '退出'):

   break

示例代码

import PySimpleGUI as sg
layout = [[sg.Button(f'按钮{i+1}') for i in range(6)]+[sg.Button('退出')]]
window = sg.Window('示例窗口', layout)
while True:
    event, values = window.read()
    if event == sg.WIN_CLOSED or event == '退出':
        break
    elif event.startswith('按钮'):
        print(f'你点击了{event}')
window.close()


调试窗口

使用sg.Print()比内置的print()更直观,它会弹出一个调试窗口:

程序会结束前点Quit退出会重新打开一个窗口;而Pause会和Resum来回切换。文本还能设置前景和背景色,参数分别为:text_color='',background_color=''。

import PySimpleGUI as sg
sg.Print('This text is white on a green background', text_color='white', background_color='green', font='Courier 10')
sg.Print('The first call sets some window settings like font that cannot be changed')
sg.Print('This is plain text just like a print would display')
sg.Print('White on Red', background_color='red', text_color='white')
sg.Print('The other print', 'parms work', 'such as sep', sep=',')
sg.Print('To not extend a colored line use the "end" parm', background_color='blue', text_color='white', end='')
sg.Print('\nThis line has no color.')


主题 theme

注意到没上面几个例程的主体和控件的背景色都是灰青色系的,这是因为它们都用了同一个默认主题theme。要使用其它色彩的主题,需要设置theme的方法: sg.theme("主题名称")

当前版本的PySimpleGUI共内置了154个主题:

>>> sg.theme_list()                                                                                                         
['Black', 'BlueMono', 'BluePurple', 'BrightColors', 'BrownBlue', 'Dark', 'Dark2', 'DarkAmber', 'DarkBlack', 'DarkBlack1', 'DarkBlue', 'DarkBlue1', 'DarkBlue10', 'DarkBlue11', 'DarkBlue12', 'DarkBlue13', 'DarkBlue14', 'DarkBlue15', 'DarkBlue16', 'DarkBlue17', 'DarkBlue2', 'DarkBlue3', 'DarkBlue4', 'DarkBlue5', 'DarkBlue6', 'DarkBlue7', 'DarkBlue8', 'DarkBlue9', 'DarkBrown', 'DarkBrown1', 'DarkBrown2', 'DarkBrown3', 'DarkBrown4', 'DarkBrown5', 'DarkBrown6', 'DarkBrown7', 'DarkGreen', 'DarkGreen1', 'DarkGreen2', 'DarkGreen3', 'DarkGreen4', 'DarkGreen5', 'DarkGreen6', 'DarkGreen7', 'DarkGrey', 'DarkGrey1', 'DarkGrey10', 'DarkGrey11', 'DarkGrey12', 'DarkGrey13', 'DarkGrey14', 'DarkGrey15', 'DarkGrey2', 'DarkGrey3', 'DarkGrey4', 'DarkGrey5', 'DarkGrey6', 'DarkGrey7', 'DarkGrey8', 'DarkGrey9', 'DarkPurple', 'DarkPurple1', 'DarkPurple2', 'DarkPurple3', 'DarkPurple4', 'DarkPurple5', 'DarkPurple6', 'DarkPurple7', 'DarkRed', 'DarkRed1', 'DarkRed2', 'DarkTanBlue', 'DarkTeal', 'DarkTeal1', 'DarkTeal10', 'DarkTeal11', 'DarkTeal12', 'DarkTeal2', 'DarkTeal3', 'DarkTeal4', 'DarkTeal5', 'DarkTeal6', 'DarkTeal7', 'DarkTeal8', 'DarkTeal9', 'Default', 'Default1', 'DefaultNoMoreNagging', 'GrayGrayGray', 'Green', 'GreenMono', 'GreenTan', 'HotDogStand', 'Kayak', 'LightBlue', 'LightBlue1', 'LightBlue2', 'LightBlue3', 'LightBlue4', 'LightBlue5', 'LightBlue6', 'LightBlue7', 'LightBrown', 'LightBrown1', 'LightBrown10', 'LightBrown11', 'LightBrown12', 'LightBrown13', 'LightBrown2', 'LightBrown3', 'LightBrown4', 'LightBrown5', 'LightBrown6', 'LightBrown7', 'LightBrown8', 'LightBrown9', 'LightGray1', 'LightGreen', 'LightGreen1', 'LightGreen10', 'LightGreen2', 'LightGreen3', 'LightGreen4', 'LightGreen5', 'LightGreen6', 'LightGreen7', 'LightGreen8', 'LightGreen9', 'LightGrey', 'LightGrey1', 'LightGrey2', 'LightGrey3', 'LightGrey4', 'LightGrey5', 'LightGrey6', 'LightPurple', 'LightTeal', 'LightYellow', 'Material1', 'Material2', 'NeutralBlue', 'Purple', 'Python', 'PythonPlus', 'Reddit', 'Reds', 'SandyBeach', 'SystemDefault', 'SystemDefault1', 'SystemDefaultForReal', 'Tan', 'TanBlue', 'TealMono', 'Topanga']
>>> len(sg.theme_list()) 
154
>>> sg.theme_previewer()  #此函数会弹出所有主题列表

主题列表:

与操作系统比较一致的主题样式是SystemDefaultForReal,设置使用sg.theme()。

下面是一个展示主题列表的例程:sg.theme('SystemDefaultForReal')

import PySimpleGUI as sg
sg.theme('SystemDefaultForReal')
layout = [[sg.Text('Theme Browser')],
          [sg.Text('Click a Theme color to see demo window')],
          [sg.Listbox(values=sg.theme_list(), size=(20, 12), key='-LIST-', enable_events=True)],
          [sg.Button('Exit')]]
window = sg.Window('Theme Browser', layout)
while True:  # Event Loop
    event, values = window.read()
    if event in (sg.WIN_CLOSED, 'Exit'):
        break
    sg.theme(values['-LIST-'][0])
    sg.popup_get_text('This is {}'.format(values['-LIST-'][0]))
window.close()

SystemDefaultForReal主题基本与操作系统的一致,也可以写作Default1或SystemDefault1。

Listbox控件

Listbox 控件是一个多选列表框,用于显示和选择多个项目。

Listbox(values, default_values=None, select_mode=None, change_submits=False, enable_events=False, bind_return_key=False, size=(None, None), s=(None, None), disabled=False, auto_size_text=None, font=None, no_scrollbar=False, horizontal_scroll=False, background_color=None, text_color=None, highlight_background_color=None, highlight_text_color=None, sbar_trough_color=None, sbar_background_color=None, sbar_arrow_color=None, sbar_width=None, sbar_arrow_width=None, sbar_frame_color=None, sbar_relief=None, key=None, k=None, pad=None, p=None, tooltip=None, expand_x=False, expand_y=False, right_click_menu=None, visible=True, metadata=None)

主要参数说明:

param values:                     list of values to display. Can be any type including mixed types as long as they have __str__ method
:type values:                      List[Any] or Tuple[Any]
:param default_values:             which values should be initially selected
:type default_values:              List[Any]
:param select_mode:                Select modes are used to determine if only 1 item can be selected or multiple and how they can be selected.   Valid choices begin with "LISTBOX_SELECT_MODE_" and include: LISTBOX_SELECT_MODE_SINGLE LISTBOX_SELECT_MODE_MULTIPLE LISTBOX_SELECT_MODE_BROWSE LISTBOX_SELECT_MODE_EXTENDED
:type select_mode:                 [enum]
:param change_submits:             DO NOT USE. Only listed for backwards compat - Use enable_events instead
:type change_submits:              (bool)
:param enable_events:              Turns on the element specific events. Listbox generates events when an item is clicked
:type enable_events:               (bool)
:param bind_return_key:            If True, then the return key will cause a the Listbox to generate an event
:type bind_return_key:             (bool)
:param size:                       w=characters-wide, h=rows-high. If an int instead of a tuple is supplied, then height is auto-set to 1
:type size:                        (int, int) |  (int, None) | int
:param s:                          Same as size parameter.  It's an alias. If EITHER of them are set, then the one that's set will be used. If BOTH are set, size will be used
:type s:                           (int, int)  | (None, None) | int
:param disabled:                   set disable state for element
:type disabled:                    (bool)
:param auto_size_text:             True if element should be the same size as the contents
:type auto_size_text:              (bool)
:param font:                       specifies the font family, size, etc.  Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
:type font:                        (str or (str, int[, str]) or None)
:param no_scrollbar:               Controls if a scrollbar should be shown.  If True, no scrollbar will be shown
:type no_scrollbar:                (bool)
:param horizontal_scroll:          Controls if a horizontal scrollbar should be shown.  If True a horizontal scrollbar will be shown in addition to vertical
:type horizontal_scroll:           (bool)
:param background_color:           color of background
:type background_color:            (str)
:param text_color:                 color of the text
:type text_color:                  (str)
:param highlight_background_color: color of the background when an item is selected. Defaults to normal text color (a reverse look)
:type highlight_background_color:  (str)
:param highlight_text_color:       color of the text when an item is selected. Defaults to the normal background color (a rerverse look)
:type highlight_text_color:        (str)
:param sbar_trough_color:           Scrollbar color of the trough
:type sbar_trough_color:            (str)
:param sbar_background_color:       Scrollbar color of the background of the arrow buttons at the ends AND the color of the "thumb" (the thing you grab and slide). Switches to arrow color when mouse is over
:type sbar_background_color:        (str)
:param sbar_arrow_color:            Scrollbar color of the arrow at the ends of the scrollbar (it looks like a button). Switches to background color when mouse is over
:type sbar_arrow_color:             (str)
:param sbar_width:                  Scrollbar width in pixels
:type sbar_width:                   (int)
:param sbar_arrow_width:            Scrollbar width of the arrow on the scrollbar. It will potentially impact the overall width of the scrollbar
:type sbar_arrow_width:             (int)
:param sbar_frame_color:            Scrollbar Color of frame around scrollbar (available only on some ttk themes)
:type sbar_frame_color:             (str)
:param sbar_relief:                 Scrollbar relief that will be used for the "thumb" of the scrollbar (the thing you grab that slides). Should be a constant that is defined at starting with "RELIEF_" - RELIEF_RAISED, RELIEF_SUNKEN, RELIEF_FLAT, RELIEF_RIDGE, RELIEF_GROOVE, RELIEF_SOLID
:type sbar_relief:                  (str)
:param key:                        Used with window.find_element and with return values to uniquely identify this element
:type key:                         str | int | tuple | object
:param k:                          Same as the Key. You can use either k or key. Which ever is set will be used.
:type k:                           str | int | tuple | object
:param pad:                        Amount of padding to put around element in pixels (left/right, top/bottom) or ((left, right), (top, bottom)) or an int. If an int, then it's converted into a tuple (int, int)
:type pad:                         (int, int) or ((int, int),(int,int)) or (int,(int,int)) or  ((int, int),int) | int
:param p:                          Same as pad parameter.  It's an alias. If EITHER of them are set, then the one that's set will be used. If BOTH are set, pad will be used
:type p:                           (int, int) or ((int, int),(int,int)) or (int,(int,int)) or  ((int, int),int) | int
:param tooltip:                    text, that will appear when mouse hovers over the element
:type tooltip:                     (str)
:param expand_x:                   If True the element will automatically expand in the X direction to fill available space
:type expand_x:                    (bool)
:param expand_y:                   If True the element will automatically expand in the Y direction to fill available space
:type expand_y:                    (bool)
:param right_click_menu:           A list of lists of Menu items to show when this element is right clicked. See user docs for exact format.
:type right_click_menu:            List[List[ List[str] | str ]]
:param visible:                    set visibility state of the element
:type visible:                     (bool)
:param metadata:                   User metadata that can be set to ANYTHING
:type metadata:                    (Any)

简单实例

表达式计算器

直接计算表达式的值:

代码如下:

import PySimpleGUI as sg
# 设置主题
sg.theme('SystemDefault1')
# 控件布局
layout = [
    [sg.Text("输入表达式:"), sg.Input(key="expression", size=(40, 1))],
    [sg.Button("计算"), sg.Button("清除"), sg.Button("退出")],
    [sg.Text("结果:"), sg.Text(key="result", size=(40, 1))],
]
# 创建窗口
window = sg.Window("计算器", layout)
# 事件循环
while True:
    event, values = window.read()
    if event == sg.WINDOW_CLOSED or event == "退出":
        break
    elif event == "清除":
        window["expression"].update("")
    elif event == "计算":
        try:
            expression = values["expression"]
            result = eval(expression)
            window["result"].update(result)
        except Exception as e:
            window["result"].update("错误:{}".format(e))
window.close()

标准计算器

外观看上去更像一点,缺点是没找到倒数和乘除法的全角符号略微有点没对齐所有的按钮。

代码如下:

import PySimpleGUI as sg
layout = [
    [sg.Input(key="expression", default_text='0',readonly=True,justification='right',
              size=(20, 1), font=("",20))],
    [sg.Button("1/x", font=("Helvetica", 24)),
     sg.Button("C",font=("Helvetica", 24)),
     sg.Button("←",font=("Helvetica", 24)),
     sg.Button(" ÷ ", font=("Helvetica", 24))],
    [sg.Button(f' {i} ', key=f"num_{i}",font=("Helvetica", 24)) for i in range(7,10)]
    +[sg.Button(" x ",font=("Helvetica", 24))],
    [sg.Button(f' {i} ', key=f"num_{i}",font=("Helvetica", 24)) for i in range(4,7)]
    +[sg.Button("-",font=("Helvetica", 24))],
    [sg.Button(f' {i} ', key=f"num_{i}",font=("Helvetica", 24)) for i in range(1,4)]
    +[sg.Button("+",font=("Helvetica", 24))],
    [sg.Button(" ± ",font=("Helvetica", 24)),
     sg.Button(" 0 ", key="num_0",font=("Helvetica", 24)),
     sg.Button("  . ",font=("Helvetica", 24)),
     sg.Button("=", font=("Helvetica", 24))],
]
window = sg.Window("计算器 by HannYang", layout)
while True:
    event, values = window.read()
    if event == sg.WINDOW_CLOSED:
        break
    elif event in ["num_{}".format(i) for i in range(10)]:
        expr = values["expression"]
        if expr=='0': expr = ''
        expr = expr + event[-1]
        window["expression"].update(expr)
    elif event == "  . ":
        expr = values["expression"]
        test = ''
        for c in expr[::-1]:
            if c not in '+-*/': test += c
            else: break
        if test!='' and '.' not in test:
            expr += "."
        window["expression"].update(expr)
    elif event in ["+", "-", " x ", " ÷ "]:
        expr = values["expression"]
        if expr[-1] not in "+-*/.":
            expr += event
            expr = expr.replace("+","+").replace("-","-")
            expr = expr.replace(" x ","*").replace(" ÷ ","/")
        window["expression"].update(expr)
    elif event == "←":
        expr = values["expression"]
        if len(expr)>0:
            expr = expr[:-1]
        if not expr:
            expr = "0"
        window["expression"].update(expr)
    elif event == "1/x":
        try:
            expr = eval("1/"+values["expression"])
            window["expression"].update(expr)
        except Exception as e:
            window["expression"].update("错误:{}".format(e))
    elif event == " ± ":
        expr = values["expression"]
        if expr[0]=='-':
            expr = expr[1:]
        else:
            expr = '-'+expr
        window["expression"].update(expr)
    elif event == "=":
        try:
            result = eval(values["expression"])
            window["expression"].update(result)
        except Exception as e:
            window["expression"].update("错误:{}".format(e))
    elif event == "C":
        window["expression"].update("0")
window.close()

小结

总之,PySimpleGUI是一个功能强大且易于使用的Python库,适用于那些想要快速构建出功能丰富的桌面应用程序的开发者。它的简洁语法和高级功能使得开发过程更加高效和愉快。无论你是初学者还是有经验的开发者,都可以尝试使用PySimpleGUI来创建出令人惊叹的GUI应用程序。

目录
相关文章
|
6月前
|
开发框架 Linux API
Qt:构建高效且用户友好的跨平台应用
Qt:构建高效且用户友好的跨平台应用
|
6月前
|
机器学习/深度学习 数据采集 人工智能
Python系列(1):简洁优雅,功能强大的编程语言
Python系列(1):简洁优雅,功能强大的编程语言
|
20天前
|
C# Python
使用wxpython开发跨平台桌面应用,对wxpython控件实现类似C#扩展函数处理的探究
【10月更文挑战第30天】使用 `wxPython` 开发跨平台桌面应用时,可以通过创建辅助类来模拟 C# 扩展函数的功能。具体步骤包括:1. 创建辅助类 `WxWidgetHelpers`;2. 在该类中定义静态方法,如 `set_button_color`;3. 在应用中调用这些方法。这种方法提高了代码的可读性和可维护性,无需修改 `wxPython` 库即可为控件添加自定义功能。但需要注意显式调用方法和避免命名冲突。
|
2月前
|
编译器 API C语言
超级好用的C++实用库之跨平台实用方法
超级好用的C++实用库之跨平台实用方法
39 6
|
5月前
|
IDE 测试技术 持续交付
Python作为一种简洁、易读且功能强大的编程语言,其自动化测试和单元测试框架的丰富性和易用性为开发者提供了极大的便利
【6月更文挑战第10天】本文探讨了Python自动化测试与单元测试框架在提升代码质量和效率中的作用。Selenium、Appium和pytest是常用的自动化测试框架,分别支持Web和移动应用的测试。unittest是Python的标准单元测试框架,提供断言方法和测试组织结构。通过制定测试计划、编写高质量测试用例、持续集成与测试、以及有效利用测试报告,开发者能提高代码质量和开发效率。
53 1
|
6月前
|
Rust JavaScript 前端开发
【一起学Rust | 框架篇 | Frui框架】rust一个对开发者友好的GUI框架——Frui
【一起学Rust | 框架篇 | Frui框架】rust一个对开发者友好的GUI框架——Frui
2389 0
|
6月前
|
编解码 开发者 UED
Qt布局实战:实现高效、美观的GUI应用程序
Qt布局实战:实现高效、美观的GUI应用程序
1060 2
|
6月前
|
机器学习/深度学习 存储 数据可视化
分享5款专注于实用简洁的工具软件
电脑上的各类软件有很多,除了那些常见的大众化软件,还有很多不为人知的小众软件,专注于实用功能,简洁干净、功能强悍。
53 0
|
6月前
|
小程序 IDE API
8月开发者日回顾|小程序开发实用工具分享
8月开发者日回顾|小程序开发实用工具分享
48 0
|
供应链 数据挖掘 Python
Python功能强大、灵活可扩展的Statsmodels库
Statsmodels是一个功能强大、灵活可扩展的Python库,用于进行统计建模和数据分析。它提供了一系列丰富的统计模型和方法,可以帮助研究人员和数据科学家在Python环境中进行高级统计分析。