最近几天在公司加班,我被安排了个“看起来很小”的需求:给测试同学做个小工具,能一键把几份日志打包发到服务器。逻辑一点都不复杂,就是平时几行脚本的事儿,但领导补了一句:“最好有个界面,点点按钮那种。”
听到这句你应该懂了,命令行那一套在非程序员眼里,等于“洪水猛兽”。那天晚上我就顺手把 PySimpleGUI 又翻出来折腾了一遍,顺便把整个过程记下来,分享给你。
用 Python 做桌面 GUI,很多人第一反应是 Tkinter,因为它是标准库,自带的。问题也很明显:
pack() / grid(),一不小心就乱成一团PyQt 这类更强,但学习曲线对很多脚本型小工具来说,真的有点过头。
PySimpleGUI 干的事就一句话:把这些底层 GUI 库包起来,用更接近“拼乐高”的方式来搭界面。底层其实还是 Tkinter / Qt / Wx,换了个更简单的皮。
你可以简单理解成:一个用“列表描述界面”的库。
在它眼里,一个窗口 = 几行组件排在一起;一行里有文字、有输入框、有按钮,这些都写在一个列表里。多个列表再放到一个大列表里,就是整个布局。
逻辑上更像这样:
window.read(),看看用户干了啥按钮、输入了啥东西听起来有点像小游戏的主循环,对吧?这就是它的“算法味儿”:事件驱动 + 状态机。
先来个最小可用例子:输入名字,点击按钮之后在窗口里打招呼。
import PySimpleGUI as sg# 布局:每一项是“一行控件”layout = [ [sg.Text("你的名字是啥?")], [sg.Input(key="-NAME-")], [sg.Button("打招呼"), sg.Button("退出")], [sg.Text("", key="-OUTPUT-")]]# 创建窗口window = sg.Window("第一个 PySimpleGUI 窗口", layout)# 事件循环whileTrue: event, values = window.read()if event in (sg.WIN_CLOSED, "退出"):breakif event == "打招呼": name = values["-NAME-"] or"陌生人" window["-OUTPUT-"].update(f"你好,{name}!")window.close()几个点你可以注意下:
layout 是一个二维列表,外层是“第几行”,内层是“这一行有哪些控件”。
每个控件都可以挂一个 key,后面 values["-NAME-"] 就是通过 key 把输入取出来。
while True 里面就是典型的事件循环:
event 是发生了什么(点了哪个按钮、关闭窗口等等)values 是当前所有输入框、选择框的值更新界面上的文字,不需要操作底层 widget,直接 window["-OUTPUT-"].update(...) 就行。
你会发现,整个逻辑非常接近我们写命令行脚本时的思路:读输入 → 处理 → 打印输出,只是这次输入输出都换成了 GUI 控件。
上面那个例子太“教学”了,给你看一个更贴近日常小工具的版本:选多个文件,假装批量处理一下,并且给个进度条。
import timeimport PySimpleGUI as sglayout = [ [sg.Text("选择要处理的文件:")], [sg.Input(key="-FILES-"), sg.FilesBrowse("浏览")], [sg.Button("开始处理"), sg.Button("退出")], [sg.ProgressBar(100, orientation="h", size=(30, 20), key="-PROG-")], [sg.Text("", key="-STATUS-")]]window = sg.Window("批量处理小工具", layout)whileTrue: event, values = window.read()if event in (sg.WIN_CLOSED, "退出"):breakif event == "开始处理": files = values["-FILES-"]ifnot files: window["-STATUS-"].update("先选文件呀~")continue file_list = files.split(";") total = len(file_list)for i, f in enumerate(file_list, start=1):# 这里写你的实际处理逻辑 time.sleep(0.2) # 模拟耗时操作 percent = int(i / total * 100) window["-PROG-"].update(percent) window["-STATUS-"].update(f"正在处理:{f}") window["-STATUS-"].update("全部搞定!")window.close()这里你能看到 PySimpleGUI 的几个“爽点”:
对那种“写给非技术同事用的小工具”来说,这种开发效率真的是救命。
等我哪天把之前那个“日志打包上传”的工具整理干净了,再单独拿出来拆一拆实现细节,现在先写到这儿,我去热个夜宵再改点代码…