Pysimplegui 简明教程

PySimpleGUI - Window Class

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

Popups have a predefined configuration of buttons, text labels and text input fields. The Window class allows you to design a GUI of more flexible design. In addition to these elements, other elements like listbox, checkbox, radio buttons, etc., are available. You can also provide a menu system to the GUI. Certain specialized widgets such as spinner, sliders, etc., can also be used to make the design more effective.

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

A window can be a non-persistent window, similar to the popups. It blocks the program flow till the user closes it by clicking a button on the client area or the close (X) button in the title bar.

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

A persistent window on the other hand continues to be visible till the event causing it to be closed occurs. The asynchronous window is the one whose contents are periodically updated.

Layout Structure

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

The placement of elements or widgets in the window’s client area is controlled by list of list objects. Each list element corresponds to one row on the window surface, and may contain one or more GUI elements available in PySimpleGUI library.

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

The first step is to visualize the placement of elements by making a drawing as follows −

layout

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

The elements on the window are placed in four rows. First three rows have a Text element (displays a static text) and an InputText element (in which user can enter). Last row has two buttons, Ok and Cancel.

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

This is represented in the list of lists as below −

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 参数值。

This list object is used as the value of layout parameter for the constructor of the Window class.

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

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

This will display the desired window. The user inputs are stored in a dictionary named as values. The read() method of Window class is called as the user presses the Ok button, and the window closes immediately.

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

The complete code to render the window is as follows −

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 显示的:

Here is the output as displayed −

layout structure

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

Enter the data as shown and press the "OK" button. The values will be printed as below −

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

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

If, after filling the data, you press the "Cancel" button, the result printed will be −

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

Persistent Window

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

Note that this window gets closed as soon as any button (or the "X" button in the title bar) is clicked. To keep the window alive till a special type of button called Exit is pressed or if the window is closed by pressing "X", the read() method is placed in an infinite loop with provision to break when WIN_CLOSED event occurs (when Exit button is pressed) or Exit event occurs (when "X" button is pressed).

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

Let us change the Cancel button in the above code with Exit button.

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 按钮。

The appearance of the window will be similar as before, except that instead of Cancel, it has Exit button.

persistent window

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

The entered data will be printed in the form of a tuple. First element is the event, i.e., the caption of button, and second is a dictionary whose key is incrementing number and value is the text entered.

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 类还有其他方法来自定义外观和行为。它们如下所列:

The important method defined in the Window class is the read() method, to collect the values entered in all input elements. The Window class has other methods to customize the appearance and behaviour. They are listed below −

Sr.No.

Method & Description

1

*AddRow*Adds a single row of elements to a window’s "self.Rows" variable

2

*AddRows*Loops through a list of lists of elements and adds each row, list, to the layout.

3

*close*Closes the window so that resources are properly freed up.

4

*disable*Disables window from taking any input from the user

5

*disappear*Causes a window to "disappear" from the screen, but remain on the taskbar.

6

*enable*Re-enables window to take user input

7

*fill*Fill in elements that are input fields with data provided as dictionary.

8

*find_element *Find element object associated with the provided key. It is equivalent to "element = window[key]"

9

*get_screen_dimensions *Get the screen dimensions.

10

*hide*Hides the window from the screen and the task bar

11

*load_from_disk*Restore values from a Pickle file created by the "SaveToDisk" function

12

*layout*Populates the window with a list of widget lists.

13

*read*Get all of your data from your Window. Pass in a timeout (in milliseconds) to wait.

14

*reappear*Causes a disappeared window to display again.

15

*save_to_disk*Saves the values contained in each of the input elements to a pickle file.

16

*set_title *Change the title of the window in taskbar

Update Window with Key

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

The data entered by the user in different input elements on the window layout is stored in the dictionary format. The dictionary keys are numbered (starting from 0) corresponding to input elements from left to right and top to bottom. We can refer to the input data by dictionary operator. That means, the data in the first element is returned by "values[0]".

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

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

It will print the following on the console −

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

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

However, if you want to manipulate the value of an element programmatically, the element must be initialized by assigning a unique string value to its key parameter. The key of an element is like the name of the variable or identifier, which makes it convenient to handle reading or assigning a value to it programmatically.

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

The key parameter should be a string. The convention is that it should be an uppercase string preceded and followed by a "-" character (Example: "- NAME-"). However, any string can be used.

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

Let us assign keys to the Input elements in the above example as shown below −

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 字典将包含键标识符而非之前的整数。

As a result, the values dictionary returned after the read() method will contain the key identifiers instead of integers previously.

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

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

Now, values[-NM-'] will fetch 'Kiran'. The key can be assigned to any element and not just the input element. You can use the same key to call Update on an element. We can use "find_element(key)" of the Window object, or use window['key'] to refer to the element.

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

Let us extend our previous example to add a row before the Ok and Cancel buttons and have an empty Text element with "-OUT-" key. On the OK event, this Text label shows the concatenation of data entered in three input elements having keys "-NM-", "-AD-" and "-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- 文本标签将按此处所示进行更新 −

Run the above code, enter text in three input elements and press OK. The -OUT- text label will be updated as shown here −

update window

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

Another example of use of key attribute is given below. To Input elements are assigned key parameters -FIRST- and -SECOND-. There are two buttons captioned Add and Sub. The Text element displays addition or subtraction of two numbers depending on the button pressed.

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()

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

The following screenshot shows the result when the "Add" button is pressed.

updated window

Borderless Window

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

By default, the application window is created with a title bar above the client area wherein all other elements are placed in the layout. The titlebar consists of a window title on the left, and the control buttons (minimize, restore/maxmimize and close) on the right. However, particularly for a kiosk-like application, there is no need of a title bar. You can get rid of the title bar by setting the "no_titlebar" property of the Window object to "True".

border window

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

To terminate such an application, the event loop must be terminated on the occurrence of Exit button event.

Window with Disabled Close

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

If you wish to prevent the user to minimize the application window, the "disable_minimize" property of the Window object should be set to True. Similarly, the True value to "disable_close" property the Close button is displayed but it doesn’t create the WINDOW_CLOSED event.

border disabled

Transparent Window

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

The "alpha_channel" property of the Window object decides the transparency of the window. Its value is between 0 to 1. By default, it is 0, which means that the window appears as opaque. Set it to 1 to make it completely transparent. Any float value between 0 to 1 makes the transparency proportional.

transparent window

Multiple Windows

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

PySimpleGUI allows more than one windows to be displayed simultaneously. The static function in PySimpleGUI module reads all the active windows when called. To make the window active, it must be finalized. The function returns a tuple of (window, event, values) structure.

window, event, values = PySimpleGUI.read_all_windows()

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

If no window is open, its return value is (None, WIN_CLOSED, None)

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

In the following code, two functions "win1()" and "win2()" create a window each when called. Starting with the first window, the button captioned Window-2 opens another window, so that both are active. When CLOSED event on first window takes place, both are closed and the program ends. If the "X" button on second window is pressed, it is marked as closed, leaving the first open.

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 窗口:

It will produce the following output windows:

multiple windows

Asynchronous Window

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

The read() method of the Window class has the following additional parameters −

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

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

The timeout parameter lets your GUIs to use in a non-blocking read situation. It is the miliseconds your device can wait before returning. It makes a window that runs on a periodic basis.

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

The longer you’re able to add to the timeout value, the less CPU time you’ll be taking. During the timeout time, you are "yielding" the processor to do other tasks. your GUI will be more responsive than if you used a nonblocking read.

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

The timeout_key parameter helps in deciding whether there has been any user action within the stipulated time. The default value of "timeout_key" is "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”属性设置为真,则窗口将始终位于当前窗口之上。

To make the window movable, set the "grab_anywhere" property of the Window object to true. If the "keep_on_top" property is set to True, the window will remain above the current windows.