我正在对一个 GUI 程序进行第一次尝试,该程序包装了一个非常基本的脚本(这样不太懂 CLI 的人也可以运行它)。
我希望的一件事是,对于那些如此倾向于的人来说,脚本仍然可以使用 CLI,并具有相同的选项。
我使用
Gooey
来实现这一点,因为对于刚入门的人来说,它似乎很好很简单,但现在我陷入了如何“切换”它的困境。
为了使用 GUI,必须使用 python 框架二进制文件来执行脚本,所以我的第一个想法是寻找使用非框架二进制文件显式调用脚本的人,并将 shebang 指向
#!/usr/bin/env pythonw
其余时间。我认为原则上这是可行的,但目前我只能想到使用简单的 if-else 进行测试。
这很好,但是,
@Gooey
装饰器需要使用GooeyParser
而不是ArgumentParser
(来自argparse
)。所以目前,这意味着我需要在代码中两次调用我的整个参数,这感觉绝对不是Pythonic。
例如:
from gooey import Gooey, GooeyParser
@Gooey(program_name="Hi I'm progam X")
def gui_args():
"""Parse GUI arguments"""
parser = GooeyParser()
parser.add_argument(
"-f",
"--file",
action="store",
widget="FileChooser",
help="Some input file."
)
from argparse import ArgumentParser
def get_args():
"""Parse command line arguments"""
parser = ArgumentParser()
parser.add_argument(
"-f",
"--file",
action="store",
help="Some input file."
)
def main():
if <some_framework_python_test>:
args = gui_args()
else:
args = get_args()
有没有一种巧妙的方法可以根据代码的启动方式在 GUI 和 CLI 行为之间切换,而无需重复代码?
我的其他想法包括基于其他一些线程切换装饰器,但它非常复杂,而且我还需要在实际代码中将
GooeyParser
切换到 ArgumentParser
。或者也许 Gooey
已经提供了这一点,而我错过了一些明显的东西(例如,我知道,Gooey
处理 argparse 风格的帮助格式。
我对Python框架也不太了解,所以我不知道我提出的建议是否可行。接受所有建议!目前,在不指定
pythonw
二进制文件的情况下运行代码只会引发 Gooey
无法找到屏幕的错误。
所以正如我所料,肯定有一种“聪明”/优雅的方式。
有一个(当前)未记录的选项
--ignore-gooey
将使脚本表现得像普通的 python 脚本。
在 github 存储库上创建了一个 问题,作者将在不久的将来对此进行记录。
Gooey
实际上在终端中吐出这个参数作为所运行命令的完整表示,并在GUI中提供了所有参数,这就是我在分派要运行的实际代码时注意到的方式。
为了获得全面的答案,如果您通常这样调用 GUI 程序*:
$ pythonw MyGooeyScript.py
要启动完整的 GUI 会话,您可以像这样调用它:
$ pythonw --ignore-gooey MyGooeyScript.py <options>
*有时需要以无缓冲模式启动 python,使用
-u
。
Chris 在这里提到https://github.com/chriskiehl/Gooey/issues/449#issuecomment-1557084961他创建的一个处理此问题的存储库:https://github.com/skeenp/gooeywrapper。
这可能对某些人有用,但我能够想出一个更简单的解决方案:
import sys
import gooey
def detect_run_mode(main_func: callable):
# Use gooey GUI only if len(sys.argv) == 1.
if len(sys.argv) > 1:
sys.argv.append("--ignore-gooey")
return main_func
class Parser:
"""Class to parse command line arguments and check run mode."""
@detect_run_mode
def __init__(self):
"""Initialize Parser."""
self.parser = build_parser()
def parse_args(self) -> gooey.GooeyParser:
"""Parse command line arguments."""
return self.parser.parse_args()
# Set up command line argument handling using Gooey.
@gooey.Gooey
def build_parser() -> gooey.GooeyParser:
# Get main parser.
parser = gooey.GooeyParser()
# Add your arguments/groups/etc.
# ...
return parser
def main():
args = Parser().parse_args()
if __name__ == "__main__":
main()