Pysimplegui 简明教程

PySimpleGUI - Window Class

弹出式窗口拥有按钮、文本标签和文本输入域的预定义配置。Window 类允许你设计出更加灵活的 GUI。除了这些元素,还提供其他元素,比如列表框、复选框、单选按钮等。你还可以向 GUI 提供菜单系统。某些专门的小部件,例如进度条、滑块等,也可以用来使设计更加有效。

窗口可以是非持久性窗口,类似于弹出式窗口。它会阻塞程序流,直至用户点击客户端区域上的按钮或标题栏上的关闭 (X) 按钮将其关闭。

另一方面,持久性窗口会一直保持可见,直至导致其关闭的事件发生。异步窗口是一种其内容会定期更新的窗口。

Layout Structure

窗口的客户端区域中元素或小部件放置由列表对像列表控制。每个列表元素对应于窗口界面上的一行,并且可以包含 PySimpleGUI 库中提供的一个或多个 GUI 元素。

第一步是通过如下方式进行绘制,可视化元素的放置位置:

layout

窗口上的元素被放置在四行中。前三行包含一个 Text 元素(显示静态文本)和一个 InputText 元素(其中用户可以输入)。最后一行包含两个按钮,Ok 和 Cancel。

这在列表列表中以如下方式表示:

import PySimpleGUI as psg
layout = [
   [psg.Text('Name '),psg.Input()],
   [psg.Text('Address '), psg.Input()],
   [psg.Text('Email ID '), psg.Input()],
   [psg.OK(), psg.Cancel()]
]

此列表对象用作 Window 类构造函数的 layout 参数值。

window = psg.Window('Form', layout)

这将显示所需的窗口。用户输入存储在名为 values 的字典中。随着用户按下 Ok 按钮,Window 类的 read() 方法被调用,并且窗口立即关闭。

用于呈现窗口的完整代码如下:

import PySimpleGUI as psg
psg.set_options(font=('Arial Bold', 16))
layout = [
   [psg.Text('Name ', size=(15,1)),psg.Input(expand_x=True)],
   [psg.Text('Address ', size=(15,1)), psg.Input(expand_x=True)],
   [psg.Text('Email ID ', size=(15,1)), psg.Input(expand_x=True)],
   [psg.OK(), psg.Cancel()]
]
window = psg.Window('Form', layout, size=(715,207))
event, values = window.read()
print (event, values)
window.close()

以下是如何 output 显示的:

layout structure

如所示输入数据并按下“OK”按钮。值会按如下方式打印:

OK {0: 'Kiran Gupta', 1: 'Mumbai', 2: 'kiran@gmail.com'}

如果在填写数据后,你按下“Cancel”按钮,打印结果将是:

Cancel {0: 'Kiran Gupta', 1: 'Mumbai', 2: 'kiran@gmail.com'}

Persistent Window

请注意,此窗口在点击任何按钮(或标题栏中的“X”按钮)后会立即关闭。若要在按下名为 Exit 的特殊类型的按钮或通过按下“X”关闭窗口时保持窗口处于活动状态,则将 read() 方法放入一个无限循环中,该循环允许在 WIN_CLOSED 事件(在按下 Exit 按钮时)或 Exit 事件(在按下“X”按钮时)发生时中断。

让我们在上面的代码中将 Cancel 按钮更改为 Exit 按钮。

import PySimpleGUI as psg
layout = [
   [psg.Text('Name '), psg.Input()],
   [psg.Text('Address '), psg.Input()],
   [psg.Text('Email ID '), psg.Input()],
   [psg.OK(), psg.Exit()]
]
window = psg.Window('Form', layout)
while True:
   event, values = window.read()
   if event == psg.WIN_CLOSED or event == 'Exit':
      break
   print (event, values)
window.close()

窗口的外观将与之前类似,只是它不再具有 Cancel 按钮,而是 Exit 按钮。

persistent window

输入的数据将以元组的形式打印。第一个元素是事件,即按钮标题,第二个元素是字典,其键是增量数字,值是输入的文本。

OK {0: 'kiran', 1: 'Mumbai', 2: 'kiran@gmail.com'}
OK {0: 'kirti', 1: 'Hyderabad', 2: 'kirti@gmail.com'}
OK {0: 'karim', 1: 'Chennai', 2: 'karim@gmail.com'}

Window Methods

Window 类中定义的重要方法是 read() 方法,用于收集所有输入元素中输入的值。Window 类还有其他方法来自定义外观和行为。它们如下所列:

Sr.No.

Method & Description

1

AddRow 将元素的单行添加到窗口的“self.Rows”变量中

2

*AddRows*循环遍历包含元素的元素列表,并向布局添加每个行(列表)。

3

*close*关闭窗口以恰当地释放资源。

4

*disable*禁止窗口获取用户的任何输入

5

*disappear*导致窗口从屏幕“消失”,但仍保留在任务栏中。

6

*enable*重新启用窗口以获取用户输入

7

*fill*填充用作字典提供的的数据作为输入字段的元素。

8

*find_element *查找与提供 的键关联的元素对象。它相当于“元素=窗口[键]”

9

*get_screen_dimensions *获取屏幕尺寸。

10

*hide*从屏幕和任务栏中隐藏窗口(窗口)。

11

*load_from_disk*从“SaveToDisk”函数创建的 Pickle 文件中恢复值

12

*layout*使用小组件列表填充窗口。

13

*read*从窗口获取所有数据。传入一个超时时间(以毫秒为单位)来等待。

14

*reappear*导致消失的窗口再次显示。

15

*save_to_disk*将包含在每个输入元素中的值保存到 pickle 文件中。

16

*set_title *更改任务栏中的窗口标题

Update Window with Key

用户在窗口布局的不同输入元素中输入的数据将以字典格式存储。字典键(从 0 开始)编号,与从左到右和从上到下的输入元素对应。我们可以通过字典运算符来引用输入数据。这意味着第一个元素中的数据由“values[0]”返回。

values = {0: 'kiran', 1: 'Mumbai', 2: 'kiran@gmail.com'}
data = [values[k] for k in values.keys()]
print (data)

它将在控制台上打印以下内容:

['kiran', 'Mumbai', 'kiran@gmail.com']

但是,如果要以编程方式操作元素的值,则必须将元素初始化为将其键参数指定为唯一的字符串值。元素的键类似于变量或标识符的名称,这使得以编程方式方便地处理读取或向其分配值。

键参数应为字符串。惯例是它应该是大写字符串,前面和后面都跟着一个“-”字符(示例:“- 名称 -”)。然而,任何字符串都可以使用。

让我们如下所示将键分配给上面的示例中的输入元素 −

layout = [
   [psg.Text('Name '),psg.Input(key='-NM-')],
   [psg.Text('Address '), psg.Input(key='-AD-')],
   [psg.Text('Email ID '), psg.Input(key='-ID-')],
   [psg.OK(), psg.Exit()],
]

结果,在 read() 方法之后返回的 values 字典将包含键标识符而非之前的整数。

OK {'-NM-': 'Kiran', '-AD-': 'Mumbai', '-ID-': 'kiran@gmail.com'}

现在,values[-NM-'] 将获取“Kiran”。可以将键分配给任何元素,而不仅仅是输入元素。可以使用相同的键对元素调用更新。我们可以使用窗口对象的“find_element(key)”或使用 window['key'] 引用该元素。

让我们扩展先前的示例,在“确定”和“取消”按钮之前添加一行,并添加一个具有“-OUT-”键的空文本元素。在“确定”事件中,此文本标签将显示在具有“-NM-”、“-AD-”和“-ID-”键的三个输入元素中输入的数据的连接。

import PySimpleGUI as psg
psg.set_options(font=('Arial Bold', 16))
layout = [
   [psg.Text('Name ', size=(15, 1)),
   psg.Input(key='-NM-', expand_x=True)],
   [psg.Text('Address ', size=(15, 1)),
   psg.Input(key='-AD-', expand_x=True)],
   [psg.Text('Email ID ', size=(15, 1)),
   psg.Input(key='-ID-', expand_x=True)],
   [psg.Text('You Entered '), psg.Text(key='-OUT-')],
   [psg.OK(), psg.Exit()],
]
window = psg.Window('Form', layout, size=(715, 200))
while True:
   event, values = window.read()
   print(event, values)
   out = values['-NM-'] + ' ' + values['-AD-'] + ' ' + values['-ID-']
   window['-OUT-'].update(out)
   if event == psg.WIN_CLOSED or event == 'Exit':
      break
window.close()

运行上述代码,在三个输入元素中输入文本并按“确定”。-OUT- 文本标签将按此处所示进行更新 −

update window

在下面提供了键属性的另一个使用示例。向输入元素分配关键参数 -FIRST- 和 -SECOND-。有两个按钮加号和减号。文本元素显示根据按下的按钮加或减两个数字。

import PySimpleGUI as psg
import PySimpleGUI as psg
psg.set_options(font=('Arial Bold', 16))
layout = [
   [psg.Text('Enter a num: '), psg.Input(key='-FIRST-')],
   [psg.Text('Enter a num: '), psg.Input(key='-SECOND-')],
   [psg.Text('Result : '), psg.Text(key='-OUT-')],
   [psg.Button("Add"), psg.Button("Sub"), psg.Exit()],
]
window = psg.Window('Calculator', layout, size=(715, 180))
while True:
   event, values = window.read()
   print(event, values)
   if event == "Add":
      result = int(values['-FIRST-']) + int(values['-SECOND-'])
   if event == "Sub":
      result = int(values['-FIRST-']) - int(values['-SECOND-'])
   window['-OUT-'].update(result)
   if event == psg.WIN_CLOSED or event == 'Exit':
      break
window.close()

以下屏幕截图显示了按下“添加”按钮时的结果。

updated window

Borderless Window

默认情况下,应用程序窗口在客户端区域上方创建标题栏,其中所有其他元素都放置在布局中。标题栏在左侧包含窗口标题,在右侧包含控件按钮(最小化、还原/最大化和关闭)。但是,特别对于类似信息亭的应用程序,不需要标题栏。可以通过将窗口对象的“no_titlebar”属性设置为“True”来摆脱标题栏。

border window

要终止此类应用程序,必须在退出按钮事件发生时终止事件循环。

Window with Disabled Close

如果你希望阻止用户最小化应用程序窗口,则应将窗口对象的“disable_minimize”属性设置为 True。类似地,对“disable_close”属性设置为 True,则关闭按钮显示,但它不会创建 WINDOW_CLOSED 事件。

border disabled

Transparent Window

窗口对象的“alpha_channel”属性决定了窗口的透明度。它的值在 0 到 1 之间。默认值为 0,这意味着窗口显示为不透明。将其设置为 1 以使其完全透明。0 到 1 之间的任何浮点数使透明度成比例。

transparent window

Multiple Windows

PySimpleGUI 允许同时显示多个窗口。PySimpleGUI 模块中的静态函数在调用时读取所有活动窗口。要激活窗口,必须对其进行最终确定。该函数返回一个(窗口、事件、值)结构的元组。

window, event, values = PySimpleGUI.read_all_windows()

如果没有打开窗口,其返回值为 (None, WIN_CLOSED, None)

在以下代码中,两个函数 “win1()” 和 “win2()” 在调用时各创建一个窗口。从第一个窗口开始,标题为“窗口-2”的按钮打开另一个窗口,以便两者都处于活动状态。当第一个窗口上发生 CLOSED 事件时,两者都关闭,程序结束。如果按下第二个窗口上的“X”按钮,则标记为已关闭,保留第一个窗口处于打开状态。

import PySimpleGUI as psg
def win1():
   layout = [
      [psg.Text('This is the FIRST WINDOW'), psg.Text('', key='-OUTPUT-')],
      [psg.Text('popup one')],
      [psg.Button('Window-2'), psg.Button('Popup'), psg.Button('Exit')]
   ]
   return psg.Window('Window Title', layout, finalize=True)
   def win2():
      layout = [
         [psg.Text('The second window')],
         [psg.Input(key='-IN-', enable_events=True)],
         [psg.Text(size=(25, 1), key='-OUTPUT-')],
         [psg.Button('Erase'), psg.popup('Popup two'), psg.Button('Exit')]]
         return psg.Window('Second Window', layout, finalize=True)
window1 = win1()
window2 = None
while True:
   window, event, values = psg.read_all_windows()
   print(window.Title, event, values)
   if event == psg.WIN_CLOSED or event == 'Exit':
      window.close()
   if window == window2:
      window2 = None
   elif window == window1:
      break
   elif event == 'Popup':
      psg.popup('Hello Popup')
   elif event == 'Window-2' and not window2:
      window2 = win2()
   elif event == '-IN-':
      window['-OUTPUT-'].update('You entered {}'.format(values["-IN-"]))
   elif event == 'Erase':
      window['-OUTPUT-'].update('')
      window['-IN-'].update('')
window.close()

它将生成以下 output 窗口:

multiple windows

Asynchronous Window

窗口类的 read() 方法具有以下附加参数 −

window.read(timeout = t, timeout_key=TIMEOUT_KEY, close=False)

timeout 参数允许你的 GUI 在非阻塞读取情况下使用。这是设备在返回之前可以等待的毫秒数。它创建一个定期运行的窗口。

你能够添加到超时值的时间越长,你占用的 CPU 时间就越少。在超时时间内,你正在“产生”处理器以执行其他任务。如果使用的是非阻塞读取,你的 GUI 将比以往更加响应。

timeout_key 参数有助于确定在规定时间内是否进行了任何用户操作。timeout_key 的默认值是“ timeout ”。

while True:
   event, value = window.read(timeout=10)
   if event == sg.WIN_CLOSED:
      break
   if event == sg.TIMEOUT_KEY:
      print("Nothing happened")

若要使窗口可移动,可将窗口对象的“grab_anywhere”属性设置为真。如果将“keep_on_top”属性设置为真,则窗口将始终位于当前窗口之上。