Turn your python functions into GUI-based applications just in a few lines of code.
Project description
PyGUIAdapterLite
目录
- PyGUIAdapterLite
- 0. 一些背景
- 1. 安装
- 2. 快速入门
- 3. 进阶用法
- 3.1 更多类型
- 3.2 错误处理与参数校验
- 3.3 配置输入控件
- 3.3.1 输入控件的可配置属性
- 3.3.2 如何配置参数控件
- 3.3.2 常用数据类型及其对应的输入控件类、配置类、常用可配置属性
- (1)
str——>StringValue - (2)
int——>IntValue - (3)
bool——>BoolValue - (4)
float——>FloatValue - (5)
Literal——>SingleChoiceValue - (6)
bool_t——>BoolValue2 - (7)
int_r——>RangedIntValue - (8)
int_s——>ScaleIntValue2 - (9)
int_ss——>ScaleIntValue - (10)
float_r——>RangedFloatValue - (11)
float_s——>ScaleFloatValue - (12)
float_ss——>ScaleFloatValue2 - (13)
text_t——>TextValue - (14)
directory_t——>DirectoryValue - (15)
dir_t——>DirectoryValue - (16)
file_t——>FileValue - (17)
color_hex_t——>HexColorValue - (18)
color_t——>HexColorValue - (19)
choice_t——>SingleChoiceValue - (20)
option_t——>SingleChoiceValue - (21)
loose_choice_t——>LooseChoiceValue - (22)
choices_t——>MultiChoiceValue - (23)
options_t——>MultiChoiceValue - (24)
string_list_t——>StringListValue - (25)
string_list——>StringListValue - (26)
str_list——>StringListValue - (27)
path_list_t——>PathListValue - (28)
path_list——>PathListValue - (29)
paths_t——>PathListValue - (30)
file_list_t——>FileListValue - (31)
file_list——>FileListValue - (32)
files_t——>FileListValue - (33)
dir_list_t——>DirectoryListValue - (34)
dir_list——>DirectoryListValue - (35)
dirs_t——>DirectoryListValue
- (1)
- 3.4 窗口配置
- 3.5 可取消的函数
- 3.6 添加多个函数
- 3.7 进度条
- 3.8 窗口菜单
- 打包应用
- 许可证
- 第三方库许可
0. 一些背景
PyGUIAdapterLite是我另一个开源项目PyGUIAdapter的Lite版本,在保持基本功能一致的情况下,聚焦于“轻量化”这一目标。因此,它去除了PyGUIAdapter中最重量级的外部依赖——Qt,使用了更轻量级的tkinter作为GUI后端。
使用tkinter最大的好处是, 它是Python的标准GUI库,绝大多数情况下随Python一起安装,不需要任何额外的步骤,这也意味着我们基本上无需考虑它与python的版本兼容性以及跨平台问题。
部分Linux发行版预装的Python中可能没有包含tkinter, 此时需要手动安装,但这非常简单,以Ubuntu-based发行版为例,可以运行类似以下命令来安装tkinter:
sudo apt-get install python3-tk
另外,tkinter非常轻量,无论是生成的可执行文件体积还是运行时的内存占用,相比于Qt(无论是PyQt还是PySide),都要小很多。
tkinter另一个潜在的优势并非技术上的,而是法律层面的,相比Qt的几个Python binding, tkinter有着更加宽松的许可证,这意味着,在法律上它更加 “安全”。
当然,tkinter相比Qt也有其劣势,主要在于功能相对简单,高级控件匮乏,外观样式不够现代化。但是对于开发一个工具类的应用来说,tkinter提供的能力已经足够了。
PyGUIAdapter和PyGUIAdapterLite的定位与另一个开源项目Gooey类似,都致力于为Python程序员提供一种极其简单的方式,为其Python程序创建一个相对整洁、美观、易用的图形用户界面,同时,允许程序员无需具备GUI编程的相关知识。
当然,如果程序员需要扩展
PyGUIAdapter[Lite],则需要了解一些GUI编程的知识。
PyGUIAdapter[Lite]和Gooey虽然目标类似,但二者在设计思想、实现机制上存在根本性的差异。
Gooey是面向命令行的,它要求程序员首先通过argparse定义命令行参数,然后再将命令行参数翻译为GUI界面。而PyGUIAdapter[Lite]则是面向函数的,函数本身已经为创建GUI界面提供了基本但必要的信息。因此,PyGUIAdapter[Lite]以函数为基本单元,通过分析函数元信息等 ,自动将函数翻译为用户界面。
总的来说,PyGUIAdapter[Lite]适用于工具类应用的开发,如果你刚好需要为你的小工具创建一个图形用户界面,但又不想在GUI代码上投入太多精力,那么,你可以尝试一下PyGUIAdapter[Lite]。
尽管
PyGUIAdapterLite已经尽可能在接口上与PyGUIAdapter保持一致,但是由于种种原因,无法保证二者接口的完全兼容。不过由于PyGUIAdapterLite本身非常简单,因此,不要求用户对PyGUIAdapter有所了解,只需要简单阅读文档,就可以上手使用。
1. 安装
PyGUIAdapterLite的wheel包已经发布到PyPI上,可以直接通过pip安装:
> pip install pyguiadapterlite
如果要体验最新功能,可以从GitHub上clone整个项目,然后自行构建:
PyGUIAdapterLite使用了poetry作为项目管理和构建工具,因此需要先安装poetry。
> git clone https://github.com/zimolab/PyGUIAdapterLite.git
> cd PyGUIAdapterLite/
> poetry install
> poetry build
2. 快速入门
使用PyGUIAdapterLite非常简单,首先准备好需要翻译为GUI界面的函数。以下面这个最简单的函数为例:
def sum_two_numbers(a: int, b: int) -> int:
"""
计算两个整数之和。
Args:
a: 第一个整数。
b: 第二个整数。
Returns:
两个整数之和。
"""
return a + b
然后,创建GUIAdapter示例,调用GUIAdapter.add()将上述函数添加到实例中,最后调用GUIAdapter.run()将该函数翻译为GUI界面:
if __name__ == "__main__":
from pyguiadapterlite import GUIAdapter
adapter = GUIAdapter()
adapter.add(sum_two_numbers)
adapter.run()
完整代码如下:
def sum_two_numbers(a: int, b: int) -> int:
"""
计算两个整数之和。
Args:
a: 第一个整数。
b: 第二个整数。
Returns:
两个整数之和。
"""
return a + b
if __name__ == "__main__":
from pyguiadapterlite import GUIAdapter
adapter = GUIAdapter()
adapter.add(sum_two_numbers)
adapter.run()
运行如上代码,PyGUIAdapterLite将生成如下界面:
上述示例虽然非常简单,但为我们展示了PyGUIAdapterLite的一些基本特性:
PyGUIAdapterLite为函数的每一个参数创建一个输入控件,输入控件的类型取决于参数的类型,而参数的类型通常通过其typing hint进行推导。PyGUIAdapterLite会读取和分析函数参数的类型注解信息,并自动匹配适合的输入控件。
也可以在不使用类型标准的情况下为参数指定输入控件类型,这涉及到
GUIAdapterLite的进阶用法。并且,无论在何种情况下,均推荐用户使用类型注解来描述函数参数。事实证明,这样做可以大大提高代码的可读性和可维护性。
PyGUIAdapterLite也会读取和分析函数的docstring,并自动生成对应的帮助信息。帮助信息包含两种类型,一种是函数的描述信息,另一种是函数的每个参数的描述信息。对于函数的描述信息,PyGUIAdapterLite会将其显示在单独的Tab页中,而对于参数的描述信息,PyGUIAdapterLite会将其显示在每个参数对应的输入控件的旁边,以tooltip的形式进行展示。
函数和参数的描述信息也可以通过其他方式进行指定,后面我们将说明这一点。
PyGUIAdapterLite会自动生成一个“Execute”按钮,用户点击该按钮后,PyGUIAdapterLite会调用函数,并将用户输入的值作为参数传递给函数。同时,PyGUIAdapterLite会捕获函数的返回值,默认情况下,PyGUIAdapterLite会弹窗显示函数的返回值,并将其显示窗口的模拟终端界面。
通过配置,可以改变上述行为,比如,禁用弹窗显示返回值,或者禁止自动打印返回值。这些配置项将在后面详细介绍。
PyGUIAdapterLite已经为内置基本类型创建了对应的输入控件,包括int、float、str、bool、enum等,下面是一个综合的示例,向你展示这些基本类型对应的输入控件默认情况下是什么样的:
import time
from enum import Enum
class FileOperation(Enum):
"""文件操作类型"""
COPY = "copy"
MOVE = "move"
RENAME = "rename"
class HashAlgorithm(Enum):
"""哈希算法类型"""
MD5 = "md5"
SHA1 = "sha1"
SHA256 = "sha256"
def batch_process_files(
source_dir: str,
target_dir: str = "",
file_pattern: str = "*",
operation: FileOperation = FileOperation.COPY,
new_name_pattern: str = "",
calculate_hash: bool = False,
hash_algorithm: HashAlgorithm = HashAlgorithm.MD5,
create_backup: bool = True,
overwrite_existing: bool = False,
file_size_limit: int = 100,
) -> str:
"""
批量处理文件的工具函数
这个函数可以批量复制、移动或重命名文件,支持文件过滤、哈希计算等功能。
非常适合用于文件整理、备份或数据迁移任务。
Args:
source_dir: 源目录路径(必须存在)
target_dir: 目标目录路径(移动/复制操作时必需)
file_pattern: 文件匹配模式,如 "*.txt"、"image_*.jpg"
operation: 文件操作类型:复制、移动或重命名
new_name_pattern: 重命名模式,如 "file_{index}.{ext}"(重命名操作时使用)
calculate_hash: 是否计算文件哈希值
hash_algorithm: 选择哈希算法
create_backup: 是否创建备份(在目标目录创建backup文件夹)
overwrite_existing: 是否覆盖已存在的文件
file_size_limit: 文件大小限制(MB),超过此大小的文件将被跳过
Returns:
处理结果的摘要信息
"""
uprint(f"源目录:{source_dir}")
uprint(f"目标目录:{target_dir}")
uprint(f"文件匹配模式:{file_pattern}")
uprint(f"文件操作类型:{operation.value}")
uprint(f"新文件名模式:{new_name_pattern}")
uprint(f"是否计算哈希值:{calculate_hash}")
uprint(f"哈希算法:{hash_algorithm.value}")
uprint(f"是否创建备份:{create_backup}")
uprint(f"是否覆盖已存在文件:{overwrite_existing}")
uprint(f"文件大小限制:{file_size_limit} MB")
uprint("开始处理...")
# 假装在处理
time.sleep(3)
uprint("处理完成!")
return "处理完成!"
if __name__ == "__main__":
from pyguiadapterlite import GUIAdapter, uprint
adapter = GUIAdapter()
adapter.add(batch_process_files)
adapter.run()
上述示例展示了PyGUIAdapterLite对基本类型参数的支持,同时,也展示了uprint()函数的用法,这个函数与内置的print()类似,用于输出一些信息,但与print()不同的是,该函数会将信息输出到窗口的模拟终端界面,而非输出到标准输出。
uprint()(或者说窗口的模拟终端界面)对ANSI提供有限支持,支持一些颜色和样式,但不支持全部特性。
同时,上述代码还隐藏这一个细节,注意到用户函数batch_process_files()中有一行time.sleep(3),这是在模拟耗时操作,当程序在运行到这一行时,我们的界面并没有冻结,这表明,在默认实现中,PyGUIAdapterLite将用户函数放在另一个线程中运行,而非在主线程(即UI线程)中,这避免了耗时操作阻塞UI线程。
在一些IO密集型的任务中,用户可能仍然会遭遇UI界面卡顿的问题,从我的实践而言,一个可能解决的方法是在用户函数中使用多进程(multiprocessing)。但这超出了本文的讨论范围,感兴趣的读者可以自行研究。
3. 进阶用法
3.1 更多类型
除了内置的基本类型,PyGUIAdapterLite还提供了一些扩展类型,这些类型基本上扩展自基本类型,但拥有更加特定和明确的语义。
所有扩展类型定义在
pyguiadapterlite.types.extendtype模块中,并且可以直接从pyguiadapterlite.types包导入。
比如,file_t类型本质上就是str类型,但在语义上它表示文件路径,针对选择文件路径的需求,该类型会提供一个特定的文件选择控件,而非str类型默认的单行文本输入框。
file_t的定义如下,可以看到,它只是简单地继承了str类型,因此,我说它本质上就是str类型:class file_t(str): passpyguiadapterlite/types/extendtypes.py
from pyguiadapterlite import GUIAdapter, uprint
from pyguiadapterlite.types import file_t
def foo(str_arg: str, file_arg: file_t):
"""
这个示例演示str、file_t类型参数控件的差异。
Args:
str_arg: 字符串参数。
file_arg: 文件路径参数。
"""
uprint(f"str_arg: {str_arg}")
uprint(f"file_arg: {file_arg}")
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(foo)
adapter.run()
除了file_t类型,PyGUIAdapterLite还提供以下扩展类型。
3.1.1 基于int的扩展类型
(1)int_r类型:有范围的整数
代表一个有范围的整数,输入控件为一个SpinBox,最大值默认为2**31 - 1, 最小值默认为-(2**31),步长默认为1。
(2)int_s类型:有范围的整数(滑动条-样式1)
代表一个有范围的整数,输入控件为一个现代样式的滑动条,最大值默认为100, 最小值默认为0。
(3)int_ss类型:有范围的整数(滑动条-样式2)
代表一个有范围的整数,输入控件为一个旧式样式的滑动条,最大值默认为100, 最小值默认为0,步长默认为1,刻度间隔默认为10。
(4) 示例
from pyguiadapterlite import GUIAdapter
from pyguiadapterlite.types import int_r, int_s, int_ss
def int_types_demo(
normal_int: int = 64,
int_r_arg: int_r = 3,
int_s_arg: int_s = 29,
int_ss_arg: int_ss = 32,
):
"""
演示基于int类型的扩展类型及其对应输入控件
"""
return int_r_arg + int_s_arg + int_ss_arg + normal_int
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(int_types_demo)
adapter.run()
其效果如下:
3.1.2 基于float的扩展类型
(1)float_r类型:有范围的浮点数
代表一个有范围的浮点数,输入控件为一个SpinBox,最大值默认为2.0**31 - 1, 最小值默认为-(2.0**31 - 1),步长默认为0.1,默认小数位数为2。
(2)float_s类型:有范围的浮点数(滑动条-样式1)
代表一个有范围的浮点数,输入控件为一个现代样式的滑动条,最大值默认为100.0, 最小值默认为-100.0。
(3)float_ss类型:有范围的浮点数(滑动条-样式2)
代表一个有范围的浮点数,输入控件为一个旧式样式的滑动条,最大值默认为100.0, 最小值默认为-100.0,步长默认为0.5,刻度间隔默认为10。
(4) 示例
from pyguiadapterlite import GUIAdapter
from pyguiadapterlite.types import float_r, float_s, float_ss
def float_types_demo(
normal_float: float = 64.0,
float_r_arg: float_r = 3.14,
float_s_arg: float_s = 29,
float_ss_arg: float_ss = 32,
):
"""
演示基于int类型的扩展类型及其对应输入控件
"""
return normal_float + float_r_arg + float_s_arg + float_ss_arg
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(float_types_demo)
adapter.run()
效果如下:
3.1.3 基于bool的扩展类型
(1)bool_t类型:单个复选框
普通bol类型的输入控件为两个互斥的单选按钮,分别表示True和False,而bool_t类型则以单个复选框的形式提供表示True/False的能力。
(2) 示例
from pyguiadapterlite import uprint, GUIAdapter
from pyguiadapterlite.types import bool_t
def bool_types_demo(normal_bool: bool, bool_t_arg: bool_t):
uprint(f"Normal bool: {normal_bool}, bool_t bool: {bool_t_arg}")
return normal_bool and bool_t_arg
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(bool_types_demo)
adapter.run()
效果如下:
3.1.4 基于str的扩展类型
(1)text_t类型:长文本输入框
提供用于多行文本输入的控件
(2)file_t类型:文件路径选择器
提供用于选择文件路径的控件
(3)directory_t类型:目录路径选择器
也可以使用其别名dir_t,提供用于选择目录路径的控件
(4)color_hex_t类型:颜色选择器
提供用于选择颜色的控件,颜色值以#开头的16进制字符串形式表示,RGB格式
(5) 示例
from pyguiadapterlite import uprint, GUIAdapter
from pyguiadapterlite.types import text_t, file_t, dir_t, color_hex_t
def str_types_demo(
long_string: text_t = "This is a long string",
file_path: file_t = "/path/to/a/file.txt",
dir_path: dir_t = "/path/to/a/directory",
color_value: color_hex_t = "#FF0000",
):
uprint("Long string:", long_string)
uprint("File path:", file_path)
uprint("Directory path:", dir_path)
uprint("Color value:", color_value)
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(str_types_demo)
adapter.run()
效果如下:
3.1.5 基于list的扩展类型
PyGUIAdapterLite提供了一些基于list类型的扩展类型,包括:
(1)string_list_t类型(字符串列表)及其示例
也可以使用其别名:str_list、string_list),用于输入一组字符串。
from pyguiadapterlite import uprint, GUIAdapter
from pyguiadapterlite.types import string_list_t
def str_list_example(str_list_arg: string_list_t):
uprint(f"len(str_list) == {len(str_list_arg)}")
for s in str_list_arg:
uprint(s)
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(str_list_example)
adapter.run()
效果如下:
添加条目界面:
编辑条目界面:
(2)path_list_t类型(路径列表)及其示例
也可以使用其别名:path_list、paths_t,用于输入一组路径(包括文件路径和目录路径)。
from pyguiadapterlite import uprint, GUIAdapter
from pyguiadapterlite.types import path_list_t
def path_list_example(path_list_arg: path_list_t):
for path in path_list_arg:
uprint(path)
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(path_list_example)
adapter.run()
效果如下:
添加路径界面:
编辑路径界面:
(3)file_list_t类型(文件路径列表)及其示例
也可以使用其别名:file_list、files_t,用于输入一组路径,仅支持选择文件路径。
from pyguiadapterlite import uprint, GUIAdapter
from pyguiadapterlite.types import file_list_t
def file_list_example(file_list_arg: file_list_t):
for file in file_list_arg:
uprint(file)
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(file_list_example)
adapter.run()
效果如下:
添加路径界面:
编辑路径界面:
(4)dir_list_t类型(目录路径列表)及其示例
也可以使用其别名:dir_list、dirs_t,用于输入一组路径,仅支持选择目录路径。
from pyguiadapterlite import uprint, GUIAdapter
from pyguiadapterlite.types import dir_list_t
def dir_list_example(dir_list_arg: dir_list_t):
for dir_path in dir_list_arg:
uprint(dir_path)
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(dir_list_example)
adapter.run()
效果如下:
添加路径界面:
编辑路径界面:
3.1.6 选项类型
有时,可能会有这样的需求,对于某些参数,我们希望用户的输入限定在一组预先提供的选项中,为此,PyGUIAdapterLite提供了一些用于支持这种需求的扩展类型,其中,既包括从一组选项中选择一个的单选类型,也包括从一组选项中选择多个的多选类型。
(1)choice_t类型(单选组)及其示例
也可以使用其别名option_t,用于生成单选组。
你可以通过如下方式,指定可选项的范围:
def your_func(arg1: choice_t = ("opt1", "opt2", "opt3")):
...
也支持将一个dict作为可选项范围,此时dict中的key将作为选项显示的文本,而其value则将作为真正传给参数的值:
def your_func(arg1: choice_t = {
"Python": 1,
"C++": 2,
"Jave": 3,
"Rust": 4
}):
...
下面是一个实际的示例,演示了上面这两种用法:
from pyguiadapterlite import uprint, GUIAdapter
from pyguiadapterlite.types import choice_t
OPTIONS = {
"Python": 1,
"C/C++": 2,
"Java": 3,
"JavaScript": 4,
"C#": 5,
"Swift": 6,
}
def choice_t_example(
choice_t_arg1: choice_t = ("choice1", "choice2", "choice3"),
choice_t_arg2: choice_t = OPTIONS,
):
uprint(f"choice_t_arg1: {choice_t_arg1}, type: {type(choice_t_arg1)}")
uprint(f"choice_t_arg2: {choice_t_arg2}, type: {type(choice_t_arg2)}")
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(choice_t_example)
adapter.run()
其效果如下:
执行用户函数,输出如下:
(2) enum.Enum(枚举类型)、typing.Literal类型(自动提取选项的单选组)及其示例
除了使用choice_t来实现单选组,PyGUIAdapterLite也支持从Enum(枚举类)和Literal类型中自动提取选项范围,生成单选组。
对于枚举类型,最终传递给参数的是所选项对应的枚举对象本身,而非该枚举对象的名称或者值。
下面是一个简单的示例,演示两种类型的用法:
from enum import Enum
from typing import Literal
from pyguiadapterlite import uprint, GUIAdapter
class Weekday(Enum):
Monday = 1
Tuesday = 2
Wednesday = 3
Thursday = 4
Friday = 5
Saturday = 6
Sunday = 7
def enum_and_literal_example(
day: Weekday = Weekday.Saturday,
favorite_fruit: Literal["apple", "banana", "orange", "grape"] = "orange",
):
uprint(f"day: {day} (type: {type(day)})")
uprint(f"favorite_fruit: {favorite_fruit} (type: {type(favorite_fruit)})")
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(enum_and_literal_example)
adapter.run()
其效果如下:
执行用户函数,输出如下:
(3) loose_choice_t(宽松的单选类型)及其示例
choice_t、Enum、Literal可以被称为__严格的单选类型__,因为用户只能从我们提供的选项中选择其一,有时,我们可能会有这种需求,即用户可以从一组预定义的选项中选择其一,同时,又允许其自行输入自定义的值。为满足这一需求,PyGUIAdapterLite提供了一种__宽松的单选类型__——loose_choice_t。
from pyguiadapterlite import uprint, GUIAdapter
from pyguiadapterlite.types import loose_choice_t
def loose_choice_example(
arg1: loose_choice_t = ("Option 1", "Option 2", "Option 3", "Option 4")
):
uprint(f"arg1: {arg1}")
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(loose_choice_example)
adapter.run()
其效果如下:
(4)choices_t类型(多选组)及其示例
PyGUIAdapterLite提供了choices_t类型,用于让用户从一组预定选项中选择0个或多个选项。
传入
choices_t类型参数的值是一个list,其中包含了用户当前选中的选项。
from pyguiadapterlite import uprint, GUIAdapter
from pyguiadapterlite.types import choices_t
ALL_CHOICES = (
"Choice 1",
"Choice 2",
"Choice 3",
"Choice 4",
"Choice 5",
"Choice 6",
)
def choices_t_example(arg: choices_t = ALL_CHOICES):
uprint(f"You selected {len(arg)} options")
if arg:
uprint(f"The options are: {arg}")
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(choices_t_example)
adapter.run()
3.2 错误处理与参数校验
增强程序健壮性的两个关键方面:一是提前检查用户的输入,发现那些非法的值,尽可能在错误发生之前就阻止它;二是尽可能预见程序可能在哪里失败,捕获可能发生的错误,并从错误中恢复。前者涉及__参数校验的话题,后者则属于错误处理的内容。PyGUIAdapterLite的设计理念是尽可能保持处于可用状态,防止整个应用因用户函数而发生crash,因此,PyGUIAdapterLite内建了一些机制,帮助开发者更加轻松的完成参数校验和错误处理__相关的工作。下面,分别就这两方面进行讨论。
3.2.1 错误处理
(1)基本策略:尽可能捕获所有异常
在默认情况下,PyGUIAdapterLite将尝试捕获用户函数中发生的任何异常/错误。因此,一般情况下,用户函数中发生的异常不会导致整个程序退出。当捕获到用户函数中发生的异常时,默认的做法是,弹出一个对话框提示用户某处发生了异常,同时,在窗口的模块终端区域打印异常的详细信息,包括trackback信息。
from pyguiadapterlite import uprint, GUIAdapter
def divide(a: int, b: int = 1):
"""尝试b输入0,引发除0异常"""
r = a / b
uprint("a/b=", r)
return r
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(divide)
adapter.run()
尽管
PyGUIAdapterLite将尝试捕获用户代码中发生的所有异常,但仍然建议开发者尽可能在自己的代码中考虑那些可能发生错误的情况,并捕获因此发生的异常。
(2)处理sys.exit()和SystemExit
在Python中,SystemExit是一类特殊的异常,通常由sys.exit()调用触发,专门用于程序退出,而不是表示错误,换言之,它的设计意图是用于表示受控的程序终止,而不同于其他表示意外情况的异常。为了错误处理逻辑的一致性,PyGUIAdapterLite也对该类异常进行了捕获,因此,用户代码中的sys.exit()调用不会导致程序退出。可用使用下面的代码验证这一点:
from pyguiadapterlite import uprint, GUIAdapter
def system_exit_example_1(arg: int):
if arg == 0:
uprint("Exiting...")
sys.exit()
else:
uprint("Not exiting...")
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(system_exit_example_1)
adapter.run()
这一默认的行为可能与用户希望的结果不符,PyGUIAdapterLite提供了方法来修改这一行为。GUIAdapter.add()有一个参数capture_system_exit_exception,当该参数设置为False时,PyGUIAdapterLite将在捕获到SystemExit后尝试退出应用。
import sys
from pyguiadapterlite import uprint, GUIAdapter
def system_exit_example_1(arg: int):
if arg == 0:
uprint("Exiting...")
sys.exit()
else:
uprint("Not exiting...")
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(system_exit_example_1, capture_system_exit_exception=False)
adapter.run()
用户应当根据自身需求,选择合适的策略。
3.2.2 参数校验
PyGUIAdapterLite提供了多种参数校验的机制,一来尽可能地简化检验的过程,二来尽可能明确地提示用户哪些是非法的参数以及参数非法的原因。
(1)利用Exception提示非法参数以及ParameterError的使用
我们可能把参数校验作为用户代码逻辑的一部分,在用户函数执行过程中检查参数,对应非法的参数,直接抛出异常即可。比如对应前面的例子,我们可用在用户函数中检查参数b的值:
from pyguiadapterlite import uprint, GUIAdapter
def divide(a: int, b: int = 1):
if b == 0:
raise ValueError("b cannot be zero")
r = a / b
uprint("a/b=", r)
return r
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(divide)
adapter.run()
这种做法的问题在于,给出非法参数并不是很明确,用户在看到异常信息后还需要自行到参数页中寻找出错的参数。为了解决这一点,PyGUIAdapterLite提供了ParameterError类型,通过抛出该类型,PyGUIAdapterLite可以自动定位出错的参数,并且闪烁参数对应的输入控件边框来提示用户。
构造
ParameterError对象,需要通过以下形式:def foo(): ... raise ParameterError(parameter_name="参数名称",message="提示信息")
from pyguiadapterlite import uprint, GUIAdapter, ParameterError
def divide(a: int, b: int = 1):
if b == 0:
raise ParameterError(parameter_name="b", message="b cannot be zero")
r = a / b
uprint("a/b=", r)
return r
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(divide)
adapter.run()
(2)通过参数校验函数进行参数校验
除了上述方法,PyGUIAdapterLite还允许开发者定义一个专门的参数校验函数,__在调用用户函数之前__对函数参数进行检查。
参数校验函数的定义应当符合如下条件:
- 函数名称任意
- 参数列表的第一个参数用于接收被校验函数的函数名称,第一个参数之后的参数为待检查的参数
- 该函数应当返回一个字典,该字典的key为非法参数的名称,value为参数非法的原因。如返回空字典,则表示不存在非法参数
举例,若用户函数定义如下:
def user_func(param1: int, param2: str, param3: file_t):
...
则,参数校验函数可以定义为如下形式:
def validate_user_func(func_name: str, **params) -> Dict[str, str]:
param1 = params.get("param1")
param2 = params.get("param2")
param3 = params.get("param3")
...
return {
"param1": "too big",
"param2": "empty string not allowed!",
"param3": "file not found!"
}
或者,不通过关键字参数而是直接获取待校验参数:
def validate_user_func(func_name: str, *, param1: int, param2: str, param3: file_t) -> Dict[str, str]:
...
return {
"param1": "too big",
"param2": "empty string not allowed!",
"param3": "file not found!"
}
当指定参数校验函数后,PyGUIAdapterLite每次正式调用用户函数前,都会用收集到的参数调用参数校验函数,若参数校验函数返回为空,则继续调用用户函数,若不为空,则表示存在非法参数,PyGUIAdapterLite终止调用用户函数,并会逐一列出这些非法的参数及其非法的原因。
开发者可以通过GUIAdapter.add()方法的parameters_validator参数指定参数校验函数。
下面是一个简单的例子,在validate()函数中,我们对backup_folder()的每一个参数进行了检查,并根据不同去情况,设置了不同的说明信息。比如,针对src_folderf参数,在未输入值时提示信息为“Source folder cannot be empty”,在src_folder指向的目录不存在时设置提示信息为“Source folder does not exist”。其他参数也是类似的逻辑。
import os
from typing import Dict
from pyguiadapterlite import uprint, GUIAdapter
from pyguiadapterlite.types import dir_t
def validate(
func_name: str, *, src_folder: dir_t, dst_folder: dir_t, max_recursion: int
) -> Dict[str, str]:
uprint(f"Validating parameters for function '{func_name}'...")
validate_errors = {}
if max_recursion < 1:
validate_errors["max_recursion"] = "Max recursion cannot be less than 1."
if not src_folder:
validate_errors["src_folder"] = "Source folder cannot be empty."
elif not os.path.isdir(src_folder):
validate_errors["src_folder"] = "Source folder does not exist."
else:
pass
if not dst_folder:
validate_errors["dst_folder"] = "Destination folder cannot be empty."
elif os.path.isdir(dst_folder) and len(os.listdir(dst_folder)) > 0:
validate_errors["dst_folder"] = "Destination folder is not empty."
else:
pass
return validate_errors
def backup_folder(src_folder: dir_t, dst_folder: dir_t, max_recursion: int = 10):
uprint(f"Backing up '{src_folder}' to '{dst_folder}'...")
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(backup_folder, parameters_validator=validate)
adapter.run()
下面是未通过校验时的效果:
下面则是所有参数均通过校验时的效果:
(3)小结
PyGUIAdapterLite提供的上述两种机制可以极大地帮助开发者简化参数校验工作,需要注意的是,上述两种方式并非互斥的,开发者完全可以同时应用两种方法,这却决于具体的业务。
3.3 配置输入控件
前面,我们介绍了PyGUIAdapterLiter支持的常用数据类型及其对应的输入控件,PyGUIAdapterLite允许开发者对参数的输入控件进行配置,以调整其外观和行为,使整个程序更加符合用户习惯和预期。
3.3.1 输入控件的可配置属性
从内部实现的角度来看,PyGUIAdapterLite的所有输入控件都继承自BaseParameterWidget基类,而BaseParameterWidget则由的BaseParameterWidgetConfig类对象进行配置。
BaseParameterWidgetConfig中定义了所有参数控件共有的属性,包括:
default_value:显示在控件中的默认值。label:函数参数标签,显示在输入组件的左侧,默认情况下为函数参数的名称。description:函数参数的描述信息,如果提供了description信息,则会在输入控件的右侧显示一个小图标(通常是问好),鼠标悬停在该处时,会通过tooltip显示description信息。group:函数参数所属的分组,当参数比较多时,可以通过分组的方式将不同类别的参数分散到不同的tab页中。如果未指定分组,则函数参数将添加到默认分组中,该分组的名称一般为“Main”。hide_label:是否隐藏函数参数标签,默认情况下,将显示函数参数标签。
BaseParameterWidgetConfig类的源代码如下:@dataclasses.dataclass(frozen=True) class BaseParameterWidgetConfig(object): default_value: Any = None label: str = "" description: str = "" group: str = "" hide_label: bool = False # noinspection PyAbstractClass @classmethod @abstractmethod def target_widget_class(cls) -> Type["BaseParameterWidget"]: raise NotImplementedError() @classmethod def new(cls, **kwargs) -> "BaseParameterWidgetConfig": return cls(**kwargs) def serialize(self) -> dict: return dataclasses.asdict(self) @classmethod def deserialize(cls, json_obj: dict) -> "BaseParameterWidgetConfig": return cls.new(**json_obj)
除了共有的属性,BaseParameterWidget的子类通常还会定义属于自己的BaseParameterWidgetConfig类,用于配置该输入控件特有的属性。
比如,str类型对应的输入控件类为StringValueWidget,其对应的配置类为StringValue,在StringValue类中,定义了StringValueWidget专属的属性,包括:
echo_char:回显字符,如果设置了该属性,则在输入控件中输入的值,将会以该字符显示,而不是实际输入的内容。非常适合密码输入场景。justify:文本对齐方式,可以设置为left、center或right。
StringValue类源代码如下:@dataclasses.dataclass(frozen=True) class StringValue(BaseParameterWidgetConfig): default_value: str = "" echo_char: str = "" justify: Literal["left", "center", "right"] = "left" @classmethod def target_widget_class(cls) -> Type["StringValueWidget"]: return StringValueWidget
又比如,int_r类型对应的输入控件类为RangedIntValueWidget,其对应的配置类为RangedIntValue,在RangedIntValue类中,定义了RangedIntValueWidget专属的属性,包括:
min_value:最小值。max_value:最大值。step:单步调整长度(步长)。wrap:是否支持循环(即输入值超过最大值时,自动回到最小值,或者输入值低于最小值时,自动回到最大值)。
@dataclasses.dataclass(frozen=True) class RangedIntValue(BaseParameterWidgetConfig): default_value: int = 0 min_value: int = MIN_VALUE max_value: int = MAX_VALUE step: int = 1 wrap: bool = False @classmethod def target_widget_class(cls) -> Type["RangedIntValueWidget"]: return RangedIntValueWidget
总结:在PyGUIAdapterLite中,一个类型对应了一个输入控件类(BaseParameterWidget子类),一个输入控件对应着一个配置类(BaseParameterWidgetConfig子类),控件的配置类管理着控件可配置的属性,配置控件本质上就是修改配置类中定义的属性。
3.3.2 如何配置参数控件
PyGUIAdapterLite提供了多种配置参数控件的方法。
(1)配置控件初始值(default_value)和描述信息(description)的简单方法
如果只是想要设置参数的默认值和描述信息,可以采用一种简单而自然的方式。
-
对于
default_value:对于绝大多数类型而言,用户函数中参数的默认值就是控件中显示的初始值,因此,如果你希望控件显示一个初始值,将对应参数的默认值设置为该值即可。这里存在一些例外情况,对于选项相关的类型,比如
choice_t/loose_choice_t/choices_t而言,参数的默认值一般被用于设置可选项范围,3.1.6 选项类型小节给出了相关演示。 -
对于
description,开发者可以通过函数的docstring进行设置。PyGUIAdapterLite支持多种风格的docstring,包括:ReST、Google、Numpydoc-style、Epydoc。def my_function_1( param1: int = 100, param2: str = "Hello World", param3: float = 3.14, param4: bool = True, ): """ This is the function description. :param param1: description of the param1 :param param2: description of the param2 :param param3: description of the param3 :param param4: description of the param4 :return: """ pass def my_function_2( param1: int = 100, param2: str = "Hello World", param3: float = 3.14, param4: bool = True, ): """ This is the function description. Args: param1: description of the param1 param2: description of the param2 param3: description of the param3 param4: description of the param4 Returns: """ pass
因此,上述示例中,两个函数
docstring中对于各个参数的描述信息都能够被正常解析,并以tooltip的形式展示出来。
(2)通过GUIAdapter.add()方法配置参数控件属性
GUIAdapter.add()方法提供了widget_configs参数,用于配置用户函数各参数的控件相关属性。开发者需要传入一个dict给参数,其中dict的key是函数参数的名称,value则为对应控件配置类的实例(前文提到的BaseParameterWidgetConfig的子类,具体某种类型对应哪个BaseParameterWidgetConfig,参考下一节)。
比如,对于以下函数:
def foo(arg1: int, arg2: float, arg3: str):
pass
其参数的控件配置可能是这样的:
{
"arg1": IntValue(
label="Argument 1",
description="This is the description of arg1",
default_value=10,
auto_correct=True,
),
"arg2": FloatValue(
label="Argument 2",
description="This is the description of arg2",
default_value=20.0,
),
"arg3": StringValue(
label="Argument 3",
description="This is the description of arg3",
default_value="Hello",
echo_char="*",
justify="center",
),
}
完整代码:
from pyguiadapterlite import GUIAdapter
from pyguiadapterlite.types import IntValue, FloatValue, StringValue
def foo(arg1: int, arg2: float, arg3: str):
pass
if __name__ == "__main__":
PARAM_CONFIGS = {
"arg1": IntValue(
label="Argument 1",
description="This is the description of arg1",
default_value=10,
auto_correct=True,
),
"arg2": FloatValue(
label="Argument 2",
description="This is the description of arg2",
default_value=20.0,
),
"arg3": StringValue(
label="Argument 3",
description="This is the description of arg3",
default_value="Hello",
echo_char="*",
justify="center",
),
}
adapter = GUIAdapter()
adapter.add(foo, widget_configs=PARAM_CONFIGS)
adapter.run()
下面是一个更加复杂一些的例子,演示了更多数据类型:
import os
from pyguiadapterlite import uprint, GUIAdapter
from pyguiadapterlite.types import (
choice_t,
int_ss,
file_t,
SingleChoiceValue,
ScaleIntValue2,
FileValue,
StringValue,
bool_t,
BoolValue2,
)
def my_function(
param1: str, param2: choice_t, param3: int_ss, param4: file_t, param5: bool_t
):
"""
This is the function description. The parameters of this function will be configured using `GUIAdapter.add()` method.
"""
uprint("param1:", param1)
uprint("param2:", param2)
uprint("param3:", param3)
uprint("param4:", param4)
uprint("param5:", param5)
if __name__ == "__main__":
PARAM_CONFIGS = {
"param1": StringValue(
label="Password",
default_value="default value of param1",
description="Input your password",
echo_char="*",
justify="center",
),
"param2": SingleChoiceValue(
label="Hash Algorithm",
choices=["MD5", "SHA1", "SHA256", "SHA512"],
default_value="SHA256",
description="Select a hash algorithm",
),
"param3": ScaleIntValue2(
label="Keep Alive Time",
default_value=10,
description="Keep alive time in minutes",
min_value=0,
max_value=20,
step=5,
tick_interval=5,
),
"param4": FileValue(
label="File to Upload",
default_value="",
description="Select a file to upload",
filters=[
("Text Files", "*.txt"),
("Python Files", "*.py"),
("All Files", "*.*"),
],
start_dir=os.getcwd(),
select_button_text="Select File",
),
"param5": BoolValue2(
label="Enable SSL",
default_value=True,
description="Enable SSL encryption",
),
}
adapter = GUIAdapter()
adapter.add(my_function, widget_configs=PARAM_CONFIGS)
adapter.run()
(3)利用函数默认值配置参数控件属性
如果函数参数的默认值被指定一个BaseParameterWidgetConfig子类对象,那么,PyGUIAdapterLite将把该对象作为该参数对应控件的配置对象。利用这一机制,上面的例子可以改写为:
import os
from pyguiadapterlite import uprint, GUIAdapter
from pyguiadapterlite.types import (
choice_t,
int_ss,
file_t,
SingleChoiceValue,
ScaleIntValue2,
FileValue,
StringValue,
bool_t,
BoolValue2,
)
#Configurations of the parameters for the function my_function
PARMA1_CONF = StringValue(
label="Password",
default_value="default value of param1",
description="Input your password",
echo_char="*",
justify="center",
)
PARMA2_CONF = SingleChoiceValue(
label="Hash Algorithm",
choices=["MD5", "SHA1", "SHA256", "SHA512"],
default_value="SHA256",
description="Select a hash algorithm",
)
PARMA3_CONF = ScaleIntValue2(
label="Keep Alive Time",
default_value=10,
description="Keep alive time in minutes",
min_value=0,
max_value=20,
step=5,
tick_interval=5,
)
PARMA4_CONF = FileValue(
label="File to Upload",
default_value="",
description="Select a file to upload",
filters=[
("Text Files", "*.txt"),
("Python Files", "*.py"),
("All Files", "*.*"),
],
start_dir=os.getcwd(),
select_button_text="Select File",
)
PARMA5_CONF = BoolValue2(
label="Enable SSL",
default_value=True,
description="Enable SSL encryption",
)
#function defined here
def my_function(
param1: str = PARMA1_CONF,
param2: choice_t = PARMA2_CONF,
param3: int_ss = PARMA3_CONF,
param4: file_t = PARMA4_CONF,
param5: bool_t = PARMA5_CONF,
):
"""
The parameters of this function will be configured using the default value of its parameters.
"""
uprint("param1:", param1)
uprint("param2:", param2)
uprint("param3:", param3)
uprint("param4:", param4)
uprint("param5:", param5)
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(my_function)
adapter.run()
(4)在docstring中配置参数控件属性
开发者可以在函数的docstring中配置参数的控件。PyGUIAdapterLite将docstring中使用@params和@end包裹起来文本块视为参数控件的配置块,配置块的格式为TOML。在配置块中,开发者可以使用如下格式配置指定参数控件属性:
[参数名称]
属性名称1 = 属性值1
属性名称2 = 属性值2
属性名称N = 属性值N
下面是一个简单的示例:
from pyguiadapterlite import uprint, GUIAdapter
from pyguiadapterlite.types import int_r, bool_t
def my_function(username: str, password: str, age: int_r, keep_logged_in: bool_t):
"""
The parameter widgets of this function will be configured in the docstring below using config block syntax.
@params
[username]
label = "Username"
default_value = "admin"
description = "Please enter your username"
[password]
label = "Password"
default_value = "123456"
description = "Please enter your password"
echo_char = "*"
[age]
label = "Age"
default_value = 25
description = "Please enter your age"
min_value = 18
max_value = 100
[keep_logged_in]
label = "Keep me logged in"
default_value = true
@end
"""
uprint(f"Username: {username}")
uprint(f"Password: {password}")
uprint(f"Age: {age}")
uprint(f"Keep logged in: {keep_logged_in}")
if __name__ == "__main__":
adapter = GUIAdapter()
adapter.add(my_function)
adapter.run()
(5)小结
前面介绍了几种配置参数控件属性的方法,这些方法并无优劣之分,开发者可以根据需要和喜好选择合适的方法来配置函数参数的控件。
3.3.2 常用数据类型及其对应的输入控件类、配置类、常用可配置属性
(1)str ——> StringValue
默认控件类:StringValueWidget
默认配置类:StringValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| echo_char | str |
"" | |
| justify | typing.Literal['left', 'center', 'right'] |
"left" |
(2)int ——> IntValue
默认控件类:IntValueWidget
默认配置类:IntValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| auto_correct | bool |
False |
用户输入非法值时,是否尝试自动修正为默认值 |
(3)bool ——> BoolValue
默认控件类:BoolValueWidget
默认配置类:BoolValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| false_text | str |
"False" |
|
| orientation | typing.Literal['horizontal', 'vertical'] |
"horizontal" |
|
| true_text | str |
"True" |
(4)float ——> FloatValue
默认控件类:FloatValueWidget
默认配置类:FloatValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| auto_correct | bool |
False |
(5)Literal ——> SingleChoiceValue
默认控件类:SingleChoiceValueWidget
默认配置类:SingleChoiceValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| choices | typing.Union[typing.List[typing.Any], typing.Dict[str, typing.Any]] |
"" | |
| columns | int |
1 |
|
| content_title | str |
"" |
(6)bool_t ——> BoolValue2
默认控件类:BoolValueWidget2
默认配置类:BoolValue2
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| hint_text | str |
"" |
(7)int_r ——> RangedIntValue
默认控件类:RangedIntValueWidget
默认配置类:RangedIntValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| max_value | int |
2147483647 |
|
| min_value | int |
-2147483647 |
|
| step | int |
1 |
|
| wrap | bool |
False |
(8)int_s ——> ScaleIntValue2
默认控件类:ScaleIntValueWidget2
默认配置类:ScaleIntValue2
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| digits | int |
0 |
|
| step | int |
1 |
|
| tick_interval | int |
10 |
(9)int_ss ——> ScaleIntValue
默认控件类:ScaleIntValueWidget
默认配置类:ScaleIntValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| cursor | str |
"hand2" |
|
| max_value | int |
100 |
|
| min_value | int |
0 |
|
| show_value | bool |
True |
(10)float_r ——> RangedFloatValue
默认控件类:RangedFloatValueWidget
默认配置类:RangedFloatValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| auto_correct | bool |
False |
|
| correct_to | typing.Literal['default', 'min', 'max', 'nearest'] |
"nearest" |
|
| decimals | int |
2 |
|
| max_value | float |
2147483647.0 |
|
| min_value | float |
-2147483647.0 |
|
| step | float |
0.1 |
(11)float_s ——> ScaleFloatValue
默认控件类:ScaleFloatValueWidget
默认配置类:ScaleFloatValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| cursor | str |
"hand2" |
|
| digits | int |
5 |
|
| max_value | float |
100.0 |
|
| min_value | float |
0.0 |
|
| show_value | bool |
True |
(12)float_ss ——> ScaleFloatValue2
默认控件类:ScaleFloatValueWidget2
默认配置类:ScaleFloatValue2
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| step | float |
0.5 |
|
| tick_interval | float |
10 |
(13)text_t ——> TextValue
默认控件类:TextValueWidget
默认配置类:TextValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| default_menu | bool |
True |
|
| font | tuple |
('Arial', 11) |
|
| height | int |
8 |
|
| wrap | typing.Literal['none', 'char', 'word'] |
"word" |
(14)directory_t ——> DirectoryValue
默认控件类:DirectoryValueWidget
默认配置类:DirectoryValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| absolutize_path | bool |
False |
|
| allow_backspace | bool |
False |
|
| dialog_title | str |
"Select Directory" |
|
| normalize_path | bool |
False |
|
| readonly | bool |
False |
|
| select_button_text | str |
"Browse" |
|
| start_dir | str |
"" |
(15)dir_t ——> DirectoryValue
默认控件类:DirectoryValueWidget
默认配置类:DirectoryValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| absolutize_path | bool |
False |
|
| allow_backspace | bool |
False |
|
| dialog_title | str |
"Select Directory" |
|
| normalize_path | bool |
False |
|
| readonly | bool |
False |
|
| select_button_text | str |
"Browse" |
|
| start_dir | str |
"" |
(16)file_t ——> FileValue
默认控件类:FileValueWidget
默认配置类:FileValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| absolutize_path | bool |
False |
|
| allow_backspace | bool |
False |
|
| dialog_title | str |
"Select File" |
|
| filters | typing.List[typing.Tuple[str, str]] |
None |
|
| normalize_path | bool |
False |
|
| readonly | bool |
False |
|
| save_file | bool |
False |
|
| select_button_text | str |
"Browse" |
|
| start_dir | str |
"" |
(17)color_hex_t ——> HexColorValue
默认控件类:HexColorValueWidget
默认配置类:HexColorValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| borderwidth | int |
1 |
|
| color_picker_title | str |
"" | |
| font | typing.Union[tuple, str] |
('Arial', 13, 'bold') |
|
| height | typing.Union[int, NoneType] |
1 |
|
| relief | typing.Literal['flat', 'raised', 'sunken', 'groove', 'ridge'] |
"flat" |
|
| show_color_code | bool |
True |
|
| show_color_picker | bool |
True |
|
| width | typing.Union[int, NoneType] |
None |
(18)color_t ——> HexColorValue
默认控件类:HexColorValueWidget
默认配置类:HexColorValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| borderwidth | int |
1 |
|
| color_picker_title | str |
"" | |
| font | typing.Union[tuple, str] |
('Arial', 13, 'bold') |
|
| height | typing.Union[int, NoneType] |
1 |
|
| relief | typing.Literal['flat', 'raised', 'sunken', 'groove', 'ridge'] |
"flat" |
|
| show_color_code | bool |
True |
|
| show_color_picker | bool |
True |
|
| width | typing.Union[int, NoneType] |
None |
(19)choice_t ——> SingleChoiceValue
默认控件类:SingleChoiceValueWidget
默认配置类:SingleChoiceValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| choices | typing.Union[typing.List[typing.Any], typing.Dict[str, typing.Any]] |
"" | |
| columns | int |
1 |
|
| content_title | str |
"" |
(20)option_t ——> SingleChoiceValue
默认控件类:SingleChoiceValueWidget
默认配置类:SingleChoiceValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| choices | typing.Union[typing.List[typing.Any], typing.Dict[str, typing.Any]] |
"" | |
| columns | int |
1 |
|
| content_title | str |
"" |
(21)loose_choice_t ——> LooseChoiceValue
默认控件类:LooseChoiceValueWidget
默认配置类:LooseChoiceValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| add_user_input | bool |
False |
|
| choices | typing.List[str] |
"" | |
| justify | typing.Literal['left', 'center', 'right'] |
"left" |
|
| readonly | bool |
False |
(22)choices_t ——> MultiChoiceValue
默认控件类:MultiChoiceValueWidget
默认配置类:MultiChoiceValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| choices | typing.Union[typing.Dict[str, typing.Any], typing.Iterable[typing.Any]] |
"" | |
| columns | int |
2 |
|
| content_title | str |
"" |
(23)options_t ——> MultiChoiceValue
默认控件类:MultiChoiceValueWidget
默认配置类:MultiChoiceValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| choices | typing.Union[typing.Dict[str, typing.Any], typing.Iterable[typing.Any]] |
"" | |
| columns | int |
2 |
|
| content_title | str |
"" |
(24)string_list_t ——> StringListValue
默认控件类:StringListValueWidget
默认配置类:StringListValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| accept_duplicates | bool |
True |
|
| accept_empty | bool |
True |
|
| add_button | bool |
True |
|
| add_button_text | str |
"Add" |
|
| add_item_dialog_label_text | str |
"Add a new item:" |
|
| add_item_dialog_title | str |
"Add Item" |
|
| add_method | typing.Literal['append', 'prepend'] |
"append" |
|
| duplicate_message | str |
"An item with the same value already exists!" |
|
| edit_item_dialog_label_text | str |
"Edit the item:" |
|
| edit_item_dialog_title | str |
"Edit Item" |
|
| empty_string_message | str |
"The string to be added cannot be empty!" |
|
| multi_selection_message | str |
"Please select only one item!" |
|
| strip | bool |
False |
(25)string_list ——> StringListValue
默认控件类:StringListValueWidget
默认配置类:StringListValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| accept_duplicates | bool |
True |
|
| accept_empty | bool |
True |
|
| add_button | bool |
True |
|
| add_button_text | str |
"Add" |
|
| add_item_dialog_label_text | str |
"Add a new item:" |
|
| add_item_dialog_title | str |
"Add Item" |
|
| add_method | typing.Literal['append', 'prepend'] |
"append" |
|
| duplicate_message | str |
"An item with the same value already exists!" |
|
| edit_item_dialog_label_text | str |
"Edit the item:" |
|
| edit_item_dialog_title | str |
"Edit Item" |
|
| empty_string_message | str |
"The string to be added cannot be empty!" |
|
| multi_selection_message | str |
"Please select only one item!" |
|
| strip | bool |
False |
(26)str_list ——> StringListValue
默认控件类:StringListValueWidget
默认配置类:StringListValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| accept_duplicates | bool |
True |
|
| accept_empty | bool |
True |
|
| add_button | bool |
True |
|
| add_button_text | str |
"Add" |
|
| add_item_dialog_label_text | str |
"Add a new item:" |
|
| add_item_dialog_title | str |
"Add Item" |
|
| add_method | typing.Literal['append', 'prepend'] |
"append" |
|
| duplicate_message | str |
"An item with the same value already exists!" |
|
| edit_item_dialog_label_text | str |
"Edit the item:" |
|
| edit_item_dialog_title | str |
"Edit Item" |
|
| empty_string_message | str |
"The string to be added cannot be empty!" |
|
| multi_selection_message | str |
"Please select only one item!" |
|
| strip | bool |
False |
(27)path_list_t ——> PathListValue
默认控件类:PathListValueWidget
默认配置类:PathListValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| absolutize_path | bool |
True |
|
| accept_duplicates | bool |
False |
|
| accept_empty | bool |
False |
|
| add_button_text | str |
"Add" |
|
| add_dir_button_text | typing.Union[str, NoneType] |
"Folder" |
|
| add_file_button_text | typing.Union[str, NoneType] |
"File" |
|
| add_method | typing.Literal['append', 'prepend'] |
"append" |
|
| add_path_dialog_label_text | str |
"Add a new path:" |
|
| add_path_dialog_title | str |
"Add Path" |
|
| dir_dialog_title | str |
"Select Directory" |
|
| duplicate_message | str |
"The path has already been added to the list!" |
|
| edit_path_dialog_label_text | str |
"Edit the path:" |
|
| edit_path_dialog_title | str |
"Edit Path" |
|
| empty_path_message | str |
"The path cannot be empty!" |
|
| file_dialog_action | typing.Literal['open', 'save'] |
"open" |
|
| file_dialog_title | str |
"Select File" |
|
| filters | typing.List[typing.Tuple[str, str]] |
"" | |
| multi_selection_message | str |
"Please select only one item!" |
|
| normalize_path | bool |
True |
|
| start_dir | str |
"" | |
| strip | bool |
True |
(28)path_list ——> PathListValue
默认控件类:PathListValueWidget
默认配置类:PathListValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| absolutize_path | bool |
True |
|
| accept_duplicates | bool |
False |
|
| accept_empty | bool |
False |
|
| add_button_text | str |
"Add" |
|
| add_dir_button_text | typing.Union[str, NoneType] |
"Folder" |
|
| add_file_button_text | typing.Union[str, NoneType] |
"File" |
|
| add_method | typing.Literal['append', 'prepend'] |
"append" |
|
| add_path_dialog_label_text | str |
"Add a new path:" |
|
| add_path_dialog_title | str |
"Add Path" |
|
| dir_dialog_title | str |
"Select Directory" |
|
| duplicate_message | str |
"The path has already been added to the list!" |
|
| edit_path_dialog_label_text | str |
"Edit the path:" |
|
| edit_path_dialog_title | str |
"Edit Path" |
|
| empty_path_message | str |
"The path cannot be empty!" |
|
| file_dialog_action | typing.Literal['open', 'save'] |
"open" |
|
| file_dialog_title | str |
"Select File" |
|
| filters | typing.List[typing.Tuple[str, str]] |
"" | |
| multi_selection_message | str |
"Please select only one item!" |
|
| normalize_path | bool |
True |
|
| start_dir | str |
"" | |
| strip | bool |
True |
(29)paths_t ——> PathListValue
默认控件类:PathListValueWidget
默认配置类:PathListValue
可配置属性:
| 字段名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| absolutize_path | bool |
True |
|
| accept_duplicates | bool |
False |
|
| accept_empty | bool |
False |
|
| add_button_text | str |
"Add" |
|
| add_dir_button_text | typing.Union[str, NoneType] |
"Folder" |
|
| add_file_button_text | typing.Union[str, NoneType] |
"File" |
|
| add_method | typing.Literal['append', 'prepend'] |
"append" |
|
| add_path_dialog_label_text | str |
"Add a new path:" |
|
| add_path_dialog_title | str |
"Add Path" |
|
| dir_dialog_title | str |
"Select Directory" |
|
| duplicate_message | str |
"The path has already been added to the list!" |
|
| edit_path_dialog_label_text | str |
"Edit the path:" |
|
| edit_path_dialog_title | str |
"Edit Path" |
|
| empty_path_message | str |
"The path cannot be empty!" |
|
| file_dialog_action | typing.Literal['open', 'save'] |
"open" |
|
| file_dialog_title | str |
"Select File" |
|
| filters | typing.List[typing.Tuple[str, str]] |
"" | |
| multi_selection_message | str |
"Please select only one item!" |
|
| normalize_path | bool |
True |
|
| start_dir | str |
"" | |
| strip | bool |
True |
(30)file_list_t ——> FileListValue
默认控件类:FileListValueWidget
默认配置类:FileListValue
可配置属性:
(31)file_list ——> FileListValue
默认控件类:FileListValueWidget
默认配置类:FileListValue
可配置属性:
(32)files_t ——> FileListValue
默认控件类:FileListValueWidget
默认配置类:FileListValue
可配置属性:
(33)dir_list_t ——> DirectoryListValue
默认控件类:DirectoryListValueWidget
默认配置类:DirectoryListValue
可配置属性:
(34)dir_list ——> DirectoryListValue
默认控件类:DirectoryListValueWidget
默认配置类:DirectoryListValue
可配置属性:
(35)dirs_t ——> DirectoryListValue
默认控件类:DirectoryListValueWidget
默认配置类:DirectoryListValue
可配置属性:
3.4 窗口配置
TODO
3.5 可取消的函数
TODO
3.6 添加多个函数
TODO
3.7 进度条
TODO
3.8 窗口菜单
TODO
打包应用
TODO
许可证
本项目使用MIT许可证,完整的许可证文本见LICENSE文件。 请在遵守相关法律法规的前提下使用本项目。
第三方库许可
本项目使用了以下优秀的开源库:
-
IconPark
- 用途:使用了IconPark部分图标,版权归IconPark所有。
- 许可:Apache License 2.0
- 许可证文件:
licenses/IconPark-LICENSE.txt - 项目地址:https://github.com/bytedance/IconPark
-
tomlkit
- 用途:解析和生成TOML格式的配置文件。
- 许可:MIT License
- 许可证文件:
licenses/tomlkit-LICENSE.txt - 项目地址:https://github.com/python-poetry/tomlkit/
-
docstring_parser
- 用途:解析Python文件的docstring。
- 许可:MIT License
- 许可证文件:
licenses/docstring_parser-LICENSE.md - 项目地址:https://github.com/rr-/docstring_parser
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyguiadapterlite-0.3.6.tar.gz.
File metadata
- Download URL: pyguiadapterlite-0.3.6.tar.gz
- Upload date:
- Size: 115.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.12.2 Windows/11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
687df3688089736270f782e792ee5baabf0dc0ef9b5cf1bf8e02269ca1b2ccb2
|
|
| MD5 |
77d50a97f9c9c5496aceedd8a017f6a9
|
|
| BLAKE2b-256 |
8c6a28ec48ba34a3b57827668454a260403e909d71908a8b61495780b596437e
|
File details
Details for the file pyguiadapterlite-0.3.6-py3-none-any.whl.
File metadata
- Download URL: pyguiadapterlite-0.3.6-py3-none-any.whl
- Upload date:
- Size: 136.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.12.2 Windows/11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f19ad470ae48226d3f81aafc463a9e8d4806ab64d20d1fa429a7b31d144da39d
|
|
| MD5 |
724ffcbde22a09c06229fe5679aeab92
|
|
| BLAKE2b-256 |
e89b776af02db676586a551ed6c2f457414020ea8e26996f97df768ad0db8df4
|