Gooey库入门

Gooey

将(几乎)任何Python3控制台程序转换为GUI程序,仅需(最少)一行代码。
Gooey使用方法与Argparse库极其相似,是Argparse库的直接替代。

快速开始

安装指南

最简单的安装方法就是通过pip
pip install Gooey
在3.10以上的版本,需要手动提前安装attrdict3
pip install attrdict3
在Linux上,还需要提前安装GTK+3工具组:

1
2
3
4
# Debian
apt install pkg-config sid/libgtk-3-dev
# RHEL
yum install pkgconfig gtk3-devel

执行pkg-config --modversion gtk+-2.0,确保正确输出
或者你也可以把Gooey项目clone到本地
git clone https://github.com/chriskiehl/Gooey.git
然后运行 setup.py
python setup.py install

基本用法

通过用一个简单的装饰器就可以将Gooey附到任何一个使用argparse传参的函数上(通常是main函数),然后Gooey就可以将你所有需要用到的参数可视化为文本框、选择框甚至是文件选择框。

1
2
3
4
5
6
from gooey import Gooey

@Gooey <---就这么简单!
def main():
parser = ArgumentParser(...)
# 剩下的代码

可以在装饰器中传参以配置不同的风格和功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 一些选项
@Gooey(advanced=true|false, # 设置是否显示高级选项
language="chinese", # 可通过json文件配置语言
auto_start=True, # 跳过所有选项页面并立刻执行程序
target=executable_cmd, # 显式设置子进程可执行文件的参数
program_name='name', # 默认程序名
program_description='desc', # 默认程序描述
default_size=(610, 530), # 默认窗口尺寸
dump_build_config=False, # 备份Gooey配置json文件
load_build_config=None, # 加载一个Gooey配置json文件
)
def main():
parser = ArgumentParser(...)
# 剩下的代码

Gooey会尽最大可能自动选择合适的控件来呈现GUI,但是如果想要手动调节,也是可以的。你可以用GooeyParser函数替代ArgumentParser函数进行实例化,然后手动添加元素:

1
2
3
4
5
6
7
8
from gooey import Gooey, GooeyParser

@Gooey
def main():
parser = GooeyParser(description="测试程序!")
parser.add_argument('Filename', widget="FileChooser")
parser.add_argument('Date', widget="DateChooser")
...

原理

Gooey可以通过装饰器的方式附在任何使用了argparse库的函数上。

1
2
3
4
5
@Gooey
def my_run_func():
parser = ArgumentParser(...)
parser.add_argument(...)
# 剩下的代码...

在运行时,它会将add_argument函数中的所有参数传递给ArgumentParser,然后进行解包并根据指定的action分配控件,最后在执行parse_args函数时自动组成GUI。
对于位置参数,Gooey会转换为必须参数,而对于选项,Gooey则会转换为可选参数。
在最简单的情况下,GUI分为输入参数的页面和输出结果的页面。

Mappings

Gooey尽最大可能根据提供的信息进行控件的映射,目前对应关系如下:

Parser Action 默认对应控件 截图
store TextField gooey1.png
store_const CheckBox gooey2.png
store_true CheckBox gooey2.png
store_false CheckBox gooey2.png
version CheckBox gooey2.png
append TextField gooey1.png
count Dropdown gooey5.png
使用add_mutually_exclusive_group()创建的互斥组中的参数 RadioGroup gooey4.png
指定了choices参数的控件 DropDown gooey3.png

当没有提供可以参考的参数时,由于默认actionstore,所以程序默认使用文本输入框控件TextField

GooeyParser

如果默认的映射关系不能满足你的需求,你也可以手动设置控件,只需要将ArgumentParser函数替换为GooeyParser,两者之间唯一的区别是后者能让你手动指定控件类型。
GooeyParser函数允许你给实例设置额外的参数widget以指定控件类型。除此之外,你不需要修改任何argparse相关的代码!
示例

1
2
3
4
5
6
7
from argparse import ArgumentParser
...

def main():
parser = ArgumentParser(description="测试程序")
parser.add_argument("name", help="this is help", action="store")
...

按照这段代码,Gooey会生成一个普通的文本框,如图所示:
gooey7.png

有以下几个值得注意的点:

  1. Python脚本文件名对应的就是程序名。
  2. description参数值会显示在标题上。
  3. name和help会显示在对应的交互控件旁边,一般是上方。

gooey9.png

如果你使用GooeyParser并提供了widget参数的值为FileChooser,那么你可以显示一个更加友好的文件选择控件:

1
2
3
4
5
6
from gooey import GooeyParser
...

def main():
parser = GooeyParser(description="测试程序")
parser.add_argument("name", help="this is help", action="store", widget="FileChooser")

gooey8.png

自定义增强控件

控件名 含义
DirChooser 目录选择
FileChooser 文件选择
MultiFileChooser 多文件选择
FileSaver 文件保存
MultiFileSaver 多文件保存
DateChooser/TimeChooser 日期/时间选择
PasswordField 密码输入
Listbox 选择列表
BlockCheckbox 带有文字描述内容的复选框,使用控件微调的checkbox_label指定文字内容
ColourChooser 选色器
FilterableDropdown 可输入式下拉列表
IntegerField 数字选择
DecimalField 小数选择
Slider 滑动条
Textarea 大型文本框

控件调整

可以在add_argument()函数中添加gooey_options以进行控件的微调。
gooey_options接受字典作为参数,也就是说,必须提供{}大括号括起来的键值对,例如:
parser.add_argument("test", gooey_options={'visible': 'true'})

可用控件 值的类型 描述
全部 label_color 六进制字符串 标签的字体颜色
全部 label_bg_color 六进制字符串 标签的背景色
全部 help_color 六进制字符串 帮助文字的颜色
全部 help_bg_color 六进制字符串 帮助文字的背景色
全部 error_color 六进制字符串 错误文字的颜色
全部 error_bg_color 六进制字符串 错误文字的背景色
全部 show_label 布尔值 是否显示标签
全部 show_help 布尔值 是否显示背景色
全部 visible 布尔值 是否显示该控件
全部 full_width 布尔值 是否强制在单行内显示控件
全部 initial_value 由控件类型决定 设置控件的默认值
Textarea height 整数 文本框的高度
Textarea readonly 布尔值 文本框是否只读
IntegerField, Slider或DecimalField min 整数或浮点数 最小值
IntegerField, Slider或DecimalField max 整数或浮点数 最大值
IntegerField, Slider或DecimalField increment 整数或浮点数 传参时的增加值
DecimalField precision 0-20的整数 浮点数精度
BlockCheckbox checkbox_label 字符串 勾选框的独立标签
Listbox height 整数 列表的高度
add_mutually_exclusive_group initial_selection 整数 默认选项
add_argument_group show_border 布尔值 显示边界线
add_argument_group show_underline 布尔值 显示下划线
add_argument_group label_color 六进制字符串 组的背景色
add_argument_group columns 整数 每行的控件数量
add_argument_group margin_top 整数 组的上边界大小
任何File或Directory相关 default_dir 字符串 默认的目录位置
任何File或Directory相关 default_file 字符串 默认的文件名
任何File或Directory相关 default_path 字符串 默认的完整路径
任何File或Directory相关 message 字符串 选择对话框中的信息
任何File或Directory相关 wildcard 字符串 可选文件类型,用”或”符号分隔,如*.*表示所有文件

国际化

Gooey支持国际化设置,只需要在@Gooey装饰器中加上一个参数:

1
2
3
@Gooey(language='russian')
def main():
...

所有程序文本都记录在外部的json文件中,所以要添加新的语言支持,只需要修改language参数即可。
可选项有:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Hindi
bosnian
chinese
croatian
czech
dutch
english
french
german
greek
hebrew
italian
japanese
korean
polish
portuguese
russian
serbian
spanish
tamil
traditional-chinese
turkish
vietnamese

全局设置

要设置Gooey的外观和功能,只需要向装饰器中传入一些参数即可:

Parameter Summary
encoding 字符的编码(默认:’utf-8’)
advanced 显示完整的选项菜单
auto_start 跳过所有选项立刻执行程序
language 选择一种语言
target Gooey的调用程序,默认使用Python
suppress_gooey_flag 如果修改target的话应当开启以防Gooey注入额外的参数
program_name 程序名,默认使用从sys.argv[0]获得的文件名
program_description 设置程序描述,默认使用ArgumentParser中的描述
default_size 默认窗口尺寸
fullscreen 全屏启动Gooey
dump_build_config 保存选项到json文件
load_build_config 加载json选项文件
image_dir 自定义图标/图片路径
language_dir Gooey搜索语言文件的路径
disable_stop_button 运行时禁用Stop按钮
show_stop_warning 运行被用户中止时发送警告
force_stop_is_error 显示成功/失败提示后立刻退出
show_success_modal 成功后是否显示总结回显
show_failure_modal 失败后是否显示总结回显
show_restart_button 是否显示Restart按钮
run_validators Gooey执行程序前是否认证
use_cmd_args 将所有运行时提供的位置参数替换为Gooey选项中的默认值
return_to_config 设为真,Gooey会在成功执行后回到选项页面
disable_progress_bar_animation 禁用进度条
show_time_remaining 禁用剩余时间显示
hide_time_remaining_on_complete 完成后禁用剩余时间显示
requires_shell 运行程序时是否需要命令行位置参数
shutdown_signal 按下Stop按钮时发送的终止信号
navigation 设置Gooey显示风格,可选项:TABBED, SIDEBAR
sidebar_title 使用SIDEBAR时,设置边栏标题,默认为”Actions”
show_sidebar 使用SIDEBAR时,是否显示边栏
header_height 标题高度
header_show_title 是否显示标题
header_show_subtitle 是否显示子标题
terminal_font_family 字体名称
terminal_font_weight 字体粗细(constants.FONTWEIGHT_NORMAL, constants.FONTWEIGHT_XXX)
terminal_font_size 字体大小
menus 显示自定义菜单
clear_before_run 执行时清理上一次的结果输出内容

自定义样式

装饰器的以下四个参数可以用于设置不同的样式:

show_sidebar=True show_sidebar=False navigation='TABBED' tabbed_groups=True

组合输入
默认搭配argparse使用Gooey时,输入被分为位置参数和选项参数。但是这并不总是用户想要的划分方式。你可以使用add_argument_group()函数将任意输出搭配为一个组合对象。

1
2
3
4
5
parser = ArgumentParser()
search_group = parser.add_argument_group(
"选项",
help="设置选项"
)

你也可以把其它参数加入组合中:

1
2
3
4
search_group.add_argument(
'--query',
help='设置内容'
)

这些参数会在UI中组合出现

执行模式

Gooey有一系列的呈现模式。

高级模式

默认的显示模式是“完整”或者说“高级”模式。这种模式下分为两种布局,由Gooey转换的命令决定。
第一种布局为平铺布局,这种布局符合大部分CLI程序(比如Curl, FFMPEG)的逻辑,一般情况下这种布局就可以了。
另一种布局是行布局。这种布局适合有多种子工具,每种都有自己的参数和选项的程序(比如Git)。这种布局会在某个位置(边栏或选项卡)显示可选操作,主界面显示给当前操作提供的参数。这种布局很适合同时提供多种功能的小程序。
每一种布局都会把传参容器作为独立的GUI组件呈现出来。

设置布局风格
布局风格由是否存在subparser决定,所以,如果你想使用行布局,首先确保使用advanced模式,然后在argparse代码中添加一个subparser

1
2
3
@gooey(advanced=True)
def main():
...

基础模式

这种模式尤其适合习惯于终端程序的用户。
只需要将@Gooey装饰器的advanced参数设为False即可

1
2
3
@gooey(advanced=False)
def main():
...

无选项模式

这种模式不提供让用户输入选项的界面,直接进入显示结果的界面并开始执行程序,适用于一部分直接执行的脚本。
启用这一模式,在@Gooey装饰器中设置auto_start=True

1
2
3
@Gooey(auto_start=True) 
def main ():
...

窗口菜单

你可以给Gooey添加一个自定义的菜单。
菜单在@Gooey装饰器中作为一组映射列表给出:

1
@Gooey(menu=[{}, {}, ...])

每组映射由两对键值对组成:

  1. name菜单组的名字
  2. items菜单组中每个项目的内容

你可以设置任意数量的菜单组,它们都会作为列表传给@Gooey装饰器的menu参数

1
2
3
@Gooey(menu=[{'name': 'File', 'items: []},
{'name': 'Tools', 'items': []},
{'name': 'Help', 'items': []}])

菜单组中的项目也是键值对的映射列表。它们的键由其type决定,但是有两个键必须设置。

  1. type设置点击菜单项的行为,同时也决定它的其它键
  2. menuTitle此菜单项的名字

目前支持四种菜单项类型:

  • AboutDialog
  • MessageDialog
  • Link
  • HtmlDialog

AboutDialog
是程序的关于对话框。它会显示程序的信息,包括名字,版本和许可证等等。

可选的内容:

  • name
  • description
  • version
  • copyright
  • license
  • website
  • developer

示例:

1
2
3
4
5
6
7
8
9
10
11
{
'type': 'AboutDialog',
'menuTitle': 'About',
'name': 'Gooey Layout Demo',
'description': 'An example of Gooey\'s layout flexibility',
'version': '1.2.1',
'copyright': '2018',
'website': 'https://github.com/chriskiehl/Gooey',
'developer': 'http://chriskiehl.com/',
'license': 'MIT'
}

MessageDialog
是通用的信息对话框,你可以通过此对话框显示任何种类的信息,比如警告。

内容:

  • message必须,信息的内容
  • caption可选,信息的标题

示例:

1
2
3
4
5
6
{
'type': 'MessageDialog',
'menuTitle': 'Information',
'message': 'Hey, here is some cool info for ya!',
'caption': 'Stuff you should know'
}

Link
用于将用户带去外部的网站,这一选项会唤出默认浏览器。

内容:

  • url完整的URL

示例:

1
2
3
4
5
{
'type': 'Link',
'menuTitle': 'Visit Out Site',
'url': 'http://www.example.com'
}

HtmlDialog
用户可以拷贝的,HTML格式的信息对话框。

内容:

  • caption可选,对话框的标题
  • html必须,在对话框中显示的HTML内容

示例:

1
2
3
4
5
6
7
8
9
10
11
12
{
'type': 'HtmlDialog',
'menuTitle': 'Fancy Dialog!',
'caption': 'Demo of the HtmlDialog',
'html': '''
<body bgcolor="white">
<img src=/path/to/your/image.png" />
<h1>Hello world!</h1>
<p><font color="red">Lorem ipsum dolor sit amet, consectetur</font></p>
</body>
'''
}

一个完整的示例
两个菜单组,各自带有不同的菜单项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@Gooey(
program_name='Advanced Layout Groups',
menu=[{
'name': 'File',
'items': [{
'type': 'AboutDialog',
'menuTitle': 'About',
'name': 'Gooey Layout Demo',
'description': 'An example of Gooey\'s layout flexibility',
'version': '1.2.1',
'copyright': '2018',
'website': 'https://github.com/chriskiehl/Gooey',
'developer': 'http://chriskiehl.com/',
'license': 'MIT'
}, {
'type': 'MessageDialog',
'menuTitle': 'Information',
'caption': 'My Message',
'message': 'I am demoing an informational dialog!'
}, {
'type': 'Link',
'menuTitle': 'Visit Our Site',
'url': 'https://github.com/chriskiehl/Gooey'
}]
},{
'name': 'Help',
'items': [{
'type': 'Link',
'menuTitle': 'Documentation',
'url': 'https://www.readthedocs.com/foo'
}]
}]
)

自定义图标

Gooey默认自带了六个图标。但是你也可以用自己的图片/图标对其进行替换,只需要告诉Gooey在初始化时搜索的路径即可。
@Gooey装饰器指定image_dir参数:

1
2
3
@Gooey(program_name='自定义图标测试', image_dir='/path/to/my/image/directory')
def main():
...

Gooey会根据文件名自动发现图片并进行替换。比如,举例来说,要替换程序图标,只需要在图片目录下添加一个名为config_icon.png的文件即可。
以下为可以覆盖的文件名:

  • program_icon.png
  • success_icon.png
  • running_icon.png
  • loading_icon.gif
  • config_icon.png
  • error_icon.png

动态参数检查

可以使用创建自定义type,并创建TypeError错误的方式进行动态参数检查,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
from gooey import Gooey, Events

# 这是自定义创建的type
def my_type(value: int):
if value <= 10:
return value # 通过,返回参数
else:
raise TypeError("数字必须大于10!") # 不通过,报错

@Gooey(use_events=[Events.VALIDATE_FORM]) # 必须手动启用此功能
def main():
parser = GooeyParser()
parser.add_argument("number", type=my_type)

打包

打包Gooey项目也很简单。
一种简单的办法是下载这个 build.spec 文件并放到程序目录下,然后编辑文件内容,修改APPPNAMEname这两项以对应你的项目,然后修改pathex项以指定程序的根目录,然后执行pyinstaller -F --windowed build.spec,就可以进行打包了。
你也可以看看 详细教程.