PySimpleGUI:快速开始
好,我们的第⼀个 GUI 程序⽤⼤家⼀般在 Python 学习阶段都⽤过的⼀个简单的模拟登录。
预设账号和密码
输⼊账号
输⼊密码
点击提交
判断账号和密码是否匹配,都匹配则返回登录成功,否则登录失败。
基本逻辑如下:
ur =input('请输⼊账号:')
password =input('请输⼊密码:')
if ur =='admin'and password =='123':
print('登录成功!')
el:
print('登录失败!')
相信很多同学都在控制台上做过这个练习。接下来呢,我们⽤ GUI 实现。
写⼀个 GUI 程序有以下步骤:
1. 理清楚需求
2. 画出原型图
炖牛肉怎么做3. 分解原型图中的元素,构造布局⽣成窗⼝
4. 获取窗⼝事件和数据
5. 运⾏事件和数据处理逻辑
6. 反馈结果
7. 重复 4~6 直到点击退出
8. 退出并销毁窗⼝
定义需求
定义需求:
⽤户在界⾯上输⼊账号和密码,当点击提交时判断账号和密码是否匹配,匹配则弹出登录成功,失败则弹出红字标识的登录失败。画原型图
好,接下来我们画⼀个原型图,画原型图⼤家可以使⽤⼀些需求⼯具:
Axure:很强⼤的原型图⼯具,但是⽤起来学习成本也⽐较⾼
Balsamiq Mockups:草图⼯具,需要购买才能使⽤
MockPlus:国产的原型图⼯具,画原型图免费,但是要导出需要收费
还有其他很多相关的原型图⼯具,请⼤家⾃⾏下载,当然你也可以直接在纸上画:
丑是丑了点,意思到了就⾏。简单的我们就直接画了,如果复杂的界⾯还是需要借助⼯具。
分解原型图并构建布局
我们来看⼀下原型图中可能会⽤到的界⾯元素(也有地⽅叫做控件、部件、组件等,我们这⾥统⼀叫做元素好了)。
1. 窗⼝标题,还有窗⼝上的 -缩⼩、□适应屏幕、x关闭。除了标题,其他⾃动构建;
2. 账号输⼊框,这⾥有两个元素:⼀个⽂本,显⽰字符串“账号”,⼀个输⼊框
3. 密码输⼊框,这⾥也有两个元素:⼀个⽂本,显⽰字符串“密码”,⼀个密码输⼊框
4. ⼀个提交按钮
5. 两个弹出窗⼝,⼀个弹出“登录成功”,另⼀个弹出红⾊⽂字的“登录失败”。
在PySimpleGUI 中布局是按⾏来处理的。每个元素都处于布局中的某⼀⾏。其中第 1 点中的标题栏不属于布局中的内容,第 5 点的弹出窗⼝属于特殊元素,不⽤加⼊布局。
我们来看看在 PySimpleGUI 中如何通过⾏来管理的:
整个布局是⼀个⼤的列表list;
每⼀⾏是这个⼤列表中的⼦列表;
每⼀⾏中的元素是这个列表的元素。
⽐如第 2 点的账号输⼊框,有两个元素,我们需要构建⼀个列表:
[⽂本,输⼊框]
整个布局应该是这样:
[
[⽂本,输⼊框],
[⽂本,输⼊框],
[按钮]
]
你的样子如果更复杂的布局,就在这个列表中添加,⽐如你想在账号输⼊框后⾯添加⼀个复选框 checkbox ⽤来勾选是否保存账号,那么布局会变成这样:
[
[⽂本,输⼊框,复选框],
[⽂本,输⼊框],
[按钮]
]第二实验小学
是不是很简单?
好了,我们还是回到我们这个⼩程序。
这⾥我们⽤到了三个元素,⽂本、输⼊框和按钮:
⽂本: Text 或者 T,它接收的第⼀个参数是要显⽰的⽂本;
输⼊框:InputText 或 Input 或 In,可以不⽤输⼊参数,是⽤来接收输⼊的单⾏⽂本。如果要⽤作密码输⼊框,那么
⽤password_char参数来指定替换的字符串,⽐如你要⽤*作为屏蔽字符,就写为password_char='*' ;
按钮: Button 或 Btn 或 B,接收的第⼀个参数是按钮显⽰的⽂本。
这⾥我们可以看到作者给出了很多简写,⽅便你使⽤但其实也增加了⼀些记忆负担,你可以在可读性的基础上记住其中⼀个就⾏。
好,那么接下来,我们就把这些元素替换到我们布局的列表中去:
import PySimpleGUI as sg # 引⼊PySimpleGUI,注意⼤⼩写
# 创建布局
layout =[
[sg.Text('账号'), sg.Input(key='_USER_')],
[sg.Text('密码'), sg.Input(password_char='*', key='_PWD_')],
[sg.Btn('提交', key='_LOGIN_')]
代理项目]
这⾥的⼀些元素加上了 key 参数,这有什么⽤?是不是都要加?
key有什么⽤? key 参数主要⽤于后⾯接收事件和获取⽤户输⼊。
是不是都要加? 像⽂本元素这种后续基本不会再处理的,可以不加。但是后续你如果要接收它的事件
天道酬勤的故事
(⽐如按钮被点击),获取⽤户输⼊(输⼊框中录⼊的数据),改变元素(⽐如某种情况触发需要改变字体颜⾊等),那么这些被操作的元素⼀定要⽤ key 参数指定⼀个唯⼀的标识。
如何加? 作者建议,使⽤⼤写字母,前后加下划线的⽅式增加标识的可读性和可识别性。
好了,⼀个布局就⽣成了,是不是很简单。
接下来把布局列表作为参数传⼊窗⼝实例就可以了:
# 创建窗⼝,⽣成窗⼝实例
window = sg.Window('登录', layout=layout, finalize=True)
Window 第⼀个参数是窗⼝标题,第⼆个参数我们传⼊了前⾯定义的布局列表,第三个参数finalize不是必须的,⽤来定型窗⼝,这主要有⼀些操作必须在窗⼝定型后才能执⾏。
接下来你运⾏⼀下就可以看到⼀个窗⼝闪了⼀下。
《震惊!这样写代码居然会让窗⼝闪⼀下就没了!》
好吧,如果你不加 finalize 参数,甚⾄闪都不会闪。我们还是把过程写完吧,这本来就是半成品。
yangsheng
事件循环
事件循环包含三个我们需要处理的过程:
获取窗⼝事件和数据
运⾏事件和数据处理逻辑
反馈结果
为什么要⽤循环?任何 GUI 窗⼝都是利⽤循环机制,不断循环接收⽤户输⼊和⽤户操作事件,然后处理,直到⽤户点击退出为⽌。如果不循环,窗⼝运⾏⼀次就会关闭。
在循环过程中,我们需要使⽤ Window 的 Read ⽅法来接收⽤户的事件和输⼊数据:
event, value = window.Read()
# event, value 的值分别是 _LOGIN_ {'_USER_': 'admin', '_PWD_': '123'}
返回的第⼀个值 event,其结果是接收界⾯的事件,这⾥是接收按钮点击事件。如果按钮被点击,event 的值将是被点击元素的 key 参数设置的标识符,⽐如我们这⾥的提交按钮的 key 设置为 _LOGI
N_,那么当提交按钮被点击时,event 的值就是 _LOGIN_。
如果没有设置 key,event 的值将会是按钮⽂本,那这⾥就会是中⽂的提交。
第⼆个返回值是 value,这是⼀个以字典形式记录接收到界⾯上的⽤户输⼊。我们之前在元素中设置的 key 参数将作为字典的键,⽐
关于动物的成语
如_USER_和_PWD_,可以通过这些 key 来取对应的输⼊值。
如果你没有为输⼊元素设置 key,那么字典的键为按照元素在 layout 中的顺序,⽤下标 0, 1, 2… 来记录⽤户输⼊的值。你就需要⽤下标按顺序去读取,如果元素很多的情况下,你很难保证正确性,因此我 建议⼀定要在元素定义的时候加上 key 参数,并且为元素设置⼀个唯⼀的标识。
三文鱼寿司
好了,接下来我们就对事件进⾏处理。
if event =='_LOGIN_':# 当获取到事件是提交按钮被点击时,处理账号密码判断
ur = value['_USER_']# 从返回值字典中提取账号输⼊框的值
password = value['_PWD_']# 从返回值字典中提取密码输⼊框的值
if ur =='admin'and password =='123':
sg.popup('登录成功!')# 弹出框
el:
sg.popup('登录失败!', text_color='red')# 弹出框的字体设置为红⾊
popup() 是 PySimpleGUI 中提供的弹出框,⽤text_color参数设置字体颜⾊。
如果你⽤的是 Pycharm,直接 Ctrl+⿏标悬停 在类名、函数名上都会看到其参数及返回值。你在调⽤时,也可以看到有哪些参数,⼤部分参数命名都能见名知义,⽤的时候多留⼼。⼤致你想要的绝⼤部分功能都能实现。
代码敲完,运⾏⼀下,是不是就可以进⾏输⼊了。但是输⼊⼀次窗⼝就关闭了,因为上⾯说过,窗⼝值运⾏⼀次就结束。要想持续保持窗⼝运⾏状态就需要加⼊循环,在特定情况(⽐如右上⾓的x和定义的元素事件)下退出循环,关闭窗⼝。
while True:# 设置⼀个循环
# 在特定条件下
break
那么什么特定条件下退出呢?⽐如某个按钮被点击或者右上⾓的x被点击。特定按钮(⽐如界⾯上定义了⼀个按钮,其 key 为 _EXIT_)的话,你直接写为:
while True:
if event =='_EXIT_':
break
对于右上⾓的x被点击,window.Read() 会接收到⼀个事件None。对,没错就是你熟悉的那个 None。那我们要响应右上⾓的x退出怎么写呢?
while True:
if event is None:
break
或者你想两个地⽅(退出按钮被点击,右上⾓x被点击)接收到事件都退出,那么写为:
while True:
if event in['_EXIT_',None]:
break
然后在循环退出后,销毁窗⼝。
其实你也发现了,就算我们不做任何处理,窗⼝也会⾃动关闭。为什么还要多写⼀句呢?这是因为在某些系统中会出现异常,因此保持良好的习惯,在循环后加上退出代码。
window.clo()
是不是⽐你⽤ input 写命令⾏复杂不了多少呢?
点获取本节完整代码。