Pysimplegui 简明教程
PySimpleGUI - Window Class
弹出式窗口拥有按钮、文本标签和文本输入域的预定义配置。Window 类允许你设计出更加灵活的 GUI。除了这些元素,还提供其他元素,比如列表框、复选框、单选按钮等。你还可以向 GUI 提供菜单系统。某些专门的小部件,例如进度条、滑块等,也可以用来使设计更加有效。
窗口可以是非持久性窗口,类似于弹出式窗口。它会阻塞程序流,直至用户点击客户端区域上的按钮或标题栏上的关闭 (X) 按钮将其关闭。
另一方面,持久性窗口会一直保持可见,直至导致其关闭的事件发生。异步窗口是一种其内容会定期更新的窗口。
Layout Structure
窗口的客户端区域中元素或小部件放置由列表对像列表控制。每个列表元素对应于窗口界面上的一行,并且可以包含 PySimpleGUI 库中提供的一个或多个 GUI 元素。
第一步是通过如下方式进行绘制,可视化元素的放置位置:
窗口上的元素被放置在四行中。前三行包含一个 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 显示的:
如所示输入数据并按下“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 按钮。
输入的数据将以元组的形式打印。第一个元素是事件,即按钮标题,第二个元素是字典,其键是增量数字,值是输入的文本。
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- 文本标签将按此处所示进行更新 −
在下面提供了键属性的另一个使用示例。向输入元素分配关键参数 -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()
以下屏幕截图显示了按下“添加”按钮时的结果。
Borderless Window
默认情况下,应用程序窗口在客户端区域上方创建标题栏,其中所有其他元素都放置在布局中。标题栏在左侧包含窗口标题,在右侧包含控件按钮(最小化、还原/最大化和关闭)。但是,特别对于类似信息亭的应用程序,不需要标题栏。可以通过将窗口对象的“no_titlebar”属性设置为“True”来摆脱标题栏。
要终止此类应用程序,必须在退出按钮事件发生时终止事件循环。
Window with Disabled Close
如果你希望阻止用户最小化应用程序窗口,则应将窗口对象的“disable_minimize”属性设置为 True。类似地,对“disable_close”属性设置为 True,则关闭按钮显示,但它不会创建 WINDOW_CLOSED 事件。
Transparent Window
窗口对象的“alpha_channel”属性决定了窗口的透明度。它的值在 0 到 1 之间。默认值为 0,这意味着窗口显示为不透明。将其设置为 1 以使其完全透明。0 到 1 之间的任何浮点数使透明度成比例。
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 窗口:
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”属性设置为真,则窗口将始终位于当前窗口之上。