3 điểm bởi GN⁺ 2023-12-10 | 1 bình luận | Chia sẻ qua WhatsApp
  • Gooey biến các ứng dụng console Python 3 thành ứng dụng GUI dễ dùng cho người dùng cuối, hoạt động bằng cách thêm một dòng decorator vào hàm có khai báo argparse
  • Cài đặt cơ bản bằng pip install Gooey, và khi dùng decorator @Gooey cùng ArgumentParser, Gooey sẽ đọc các tham số để dựng UI dựa trên các thành phần WX
  • Khi lựa chọn widget mặc định không đủ, có thể thay ArgumentParser bằng GooeyParser và chỉ định tham số widget để chọn widget tùy chỉnh như FileChooser, DateChooser, PasswordField, Slider
  • Đối tượng phù hợp không phải là công cụ dành cho lập trình viên trực tiếp thao tác CLI, mà là các script kiểu “chạy rồi xong” dùng trong văn phòng hoặc công cụ cho người không lập trình; hỗ trợ chế độ chạy nâng cao/cơ bản/không cấu hình, menu, thanh tiến trình, quốc tế hóa, thay icon và đóng gói
  • Xác thực động và các sự kiện vòng đời được đánh dấu là tính năng thử nghiệm; hiện không hỗ trợ optparse và giả định mã nguồn dựa trên ArgumentParser cùng cơ chế đăng ký sự kiện tùy chọn

Cách biến chương trình console thành GUI

  • Gooey chuyển ứng dụng console thành ứng dụng GUI dễ thao tác cho người dùng cuối
  • Cách dùng cốt lõi là thêm decorator @Gooey vào hàm có khai báo argparse
from gooey import Gooey

@Gooey
def main():
  parser = ArgumentParser(...)

# rest of code
  • Kiểu dáng và hành vi có thể điều chỉnh bằng các tham số của decorator
    • advanced: có hiển thị màn hình thiết lập nâng cao hay không
    • language: chọn bản dịch dựa trên JSON
    • auto_start: bỏ qua màn hình thiết lập và chạy ngay
    • target: chỉ định lệnh sẽ chạy dưới dạng tiến trình con
    • program_name, program_description: tên hiển thị và mô tả trong GUI
    • default_size: kích thước khởi tạo của GUI
    • dump_build_config, load_build_config: lưu/tải JSON cấu hình build của Gooey
    • monospace_display: dùng font đơn cách cho màn hình đầu ra

Cài đặt và ví dụ

  • Cách cài đặt dễ nhất là dùng pip
pip install Gooey
  • Cũng có thể clone kho mã rồi chạy setup.py để cài đặt
git clone https://github.com/chriskiehl/Gooey.git
python setup.py install
  • Các script ví dụ dựng sẵn có thể lấy từ kho Gooey Examples
  • Kho ví dụ được cung cấp để xem qua nhiều bố cục, widget và tính năng của Gooey

Vì sao cần nó

  • Gooey được tạo ra để giảm vấn đề phải đưa dấu nhắc lệnh cho những người dùng không quen với command prompt
  • Khi chương trình cần làm một hay nhiều tác vụ, nó phải nhận tùy chọn, và trước đây либо phải tự làm GUI hoặc phải giải thích cách truyền tham số cho ứng dụng console
  • Gooey cho phép lập trình viên tạo chương trình theo cách cấu hình quen thuộc, đồng thời cung cấp phần hiển thị và tương tác qua GUI

Người dùng phù hợp và trường hợp không phù hợp

  • Gooey có thể không phù hợp với các tiện ích dành cho chính bạn hoặc cho lập trình viên khác, hay các công cụ tạo kết quả để pipe sang ứng dụng console khác
  • Nó phù hợp với script chạy trong văn phòng, công cụ chuyển dữ liệu từ điểm A sang điểm B, và các chương trình dành cho người không lập trình
  • Mục tiêu là xây ứng dụng phức tạp mà có thêm phần GUI gần như không tốn chi phí bổ sung

Cách hoạt động bên trong và ánh xạ argparse

  • Gooey phân tích tham chiếu ArgumentParser trong script Python tại thời gian chạy
  • Hiện chưa hỗ trợ optparse
  • Các tham số được trích xuất sẽ được gán loại thành phần theo action được cung cấp và dùng để dựng GUI
  • ArgumentParser._actions mặc định được ánh xạ sang các thành phần WX như sau
    • store: TextCtrl
    • store_const, store_true, store_False, version: CheckBox
    • append: TextCtrl
    • count: DropDown
    • Mutually Exclusive Group: RadioGroup
    • choice: DropDown

GooeyParser và widget tùy chỉnh

  • Nếu lựa chọn widget mặc định chưa đủ, có thể dùng GooeyParser, một thay thế drop-in cho ArgumentParser
  • GooeyParser cung cấp thêm tham số từ khóa widget để chỉ định tên thành phần sẽ hiển thị
from gooey import Gooey, GooeyParser

@Gooey
def main():
  parser = GooeyParser(description="My Cool GUI Program!")
  parser.add_argument('Filename', widget="FileChooser")
  parser.add_argument('Date', widget="DateChooser")
  • Các widget tùy chỉnh được hỗ trợ gồm
    • DirChooser, FileChooser, MultiFileChooser
    • FileSaver, MultiFileSaver
    • DateChooser, TimeChooser
    • PasswordField
    • Listbox
    • BlockCheckbox
    • ColourChooser
    • FilterableDropdown
    • IntegerField, DecimalField
    • Slider
  • Giá trị mà DateChooserTimeChooser truyền vào ứng dụng luôn ở định dạng ISO, dù một số phần của GUI có thể hiển thị giá trị đã bản địa hóa theo thiết lập của người dùng cuối
  • BlockCheckbox chuyển khối văn bản ra vị trí thông thường để dễ nhìn hơn so với checkbox inline mặc định khi có phần trợ giúp dài, đồng thời hiển thị block_label ngắn bên cạnh control

Quốc tế hóa

  • Gooey chọn ngôn ngữ hiển thị bằng tham số language của decorator
@Gooey(language='russian')
def main():
    ...
  • Toàn bộ văn bản của chương trình được lưu trong các tệp JSON bên ngoài
  • Hỗ trợ ngôn ngữ mới được thêm bằng cách bổ sung cặp khóa/giá trị trong thư mục gooey/languages/
  • Hiện có sẵn hơn 18 bản dịch mặc định

Cấu hình toàn cục và thiết lập UI

  • Hình thức và hành vi tổng thể của Gooey được điều chỉnh bằng các tham số decorator
  • Các thiết lập chính gồm
    • encoding: mã hóa ký tự hiển thị, mặc định là utf-8
    • advanced: chọn màn hình thiết lập đầy đủ hoặc bản đơn giản hóa
    • auto_start: chạy ngay không qua cấu hình
    • target: chỉ định cách Gooey tự chạy lại chính nó
    • suppress_gooey_flag: ngăn chèn thêm tham số CLI khi dùng target tùy chỉnh
    • fullscreen: khởi động ở chế độ toàn màn hình
    • image_dir: thư mục ảnh/icon tùy chỉnh
    • language_dir: thư mục tệp ngôn ngữ tùy chỉnh
    • disable_stop_button, show_stop_warning: điều khiển nút dừng và cảnh báo khi đang chạy
    • show_success_modal, show_failure_modal: có hiển thị modal tóm tắt thành công/thất bại hay không
    • run_validators: có chạy kiểm tra trước khi gọi chương trình hay không
    • progress_regex, progress_expr: phân tích và chuyển đổi văn bản tiến trình
    • navigation: TABBED hoặc SIDEBAR
    • body_bg_color, header_bg_color, footer_bg_color, sidebar_bg_color: cấu hình màu sắc
    • terminal_font_family, terminal_font_size, terminal_font_color: cấu hình font cho phần hiển thị terminal
    • menus: nhóm menu và mục menu tùy chỉnh
    • clear_before_run: xóa đầu ra cũ khi chạy lại

Bố cục và chế độ chạy

  • Gooey mặc định chia đầu vào thành hai nhóm positionaloptional
  • Khi dùng argparse với add_argument_group(), có thể gom đầu vào thành các nhóm logic và điều chỉnh bố cục từng nhóm
parser = ArgumentParser()
search_group = parser.add_argument_group(
    "Search Options",
    "Customize the search options"
)
search_group.add_argument(
    '--query',
    help='Base search string'
)
  • Các tùy chọn bố cục toàn cục được hỗ trợ gồm show_sidebar=True, show_sidebar=False, navigation='TABBED', tabbed_groups=True
  • Advanced

    • Màn hình mặc định là màn hình thiết lập full/advanced
    • Với đa số ứng dụng, bố cục phẳng phù hợp với cấu trúc CLI là lựa chọn phù hợp
    • Với CLI gồm nhiều nhánh hoặc tổ hợp nhiều công cụ nhỏ, bố cục cột sẽ phù hợp hơn
    • Bố cục cột hiển thị đường dẫn chính ở cột bên trái và các tham số tương ứng ở bên phải
    • Hiện chưa thể chỉ định rõ bố cục bằng tham số; việc này được quyết định dựa trên việc mã có subparsers hay không
  • Basic

    • Đặt advanced=False sẽ chuyển sang chế độ xem cơ bản
    • Phù hợp khi người dùng đã quen với ứng dụng console nhưng muốn giao diện gọn gàng hơn terminal đơn thuần
    @gooey(advanced=False)
    def main():
    
    # rest of code
    
  • No Config

    • Đặt auto_start=True sẽ bỏ qua màn hình cấu hình và đi thẳng tới vùng hiển thị để chạy chương trình host
    • Dùng để cải thiện vẻ ngoài cho các script nhỏ, dùng một lần
    @Gooey(auto_start=True)
    def main():
        ...
    

Tính năng menu

  • Từ Gooey 1.0.2, có thể thêm Menu Bar ở phía trên
  • Menu được chỉ định dưới dạng danh sách map kiểu @Gooey(menu=[{}, {}, ...])
  • Mỗi nhóm menu có nameitems
  • Mỗi mục menu luôn gồm typemenuTitle
  • Các kiểu mục menu được hỗ trợ gồm
    • AboutDialog: hiển thị thông tin chương trình như tên, phiên bản, giấy phép
    • MessageDialog: hiển thị thông báo thông tin cho người dùng
    • Link: mở URL được chỉ định bằng trình duyệt mặc định
    • HtmlDialog: hiển thị hộp thoại dùng tập con HTML giới hạn

Xác thực động

  • Dynamic Validation là tính năng thử nghiệm và API có thể thay đổi hoặc bị loại bỏ
  • Gooey có thể tùy chọn thực hiện kiểm tra trước khi chuyển đầu vào người dùng cho chương trình
  • Tính năng này tận dụng tham số type, vốn dùng được với hầu hết kiểu tham số của Argparse
def must_be_exactly_ten(value):
    number = int(value)
    if number == 10:
        return number
    else:
        raise TypeError("Hey! you need to provide exactly the number 10!")
  • Việc xác thực không chạy theo mặc định
  • Để bật, cần đăng ký sự kiện VALIDATE_FORM
from gooey import Gooey, Events

@Gooey(use_events=[Events.VALIDATE_FORM])
def main():
    ...
  • Tính năng này hiện là opt-in vì bên trong sử dụng Monkey Patching khá mạnh

Sự kiện vòng đời và điều khiển UI

  • Từ Gooey 1.2.0, chương trình được mở ra các hook vòng đời
  • Tính năng này cũng là thử nghiệm và API có thể thay đổi hoặc bị loại bỏ
  • Hiện có hai hook chính
    • on_success
    • on_error
  • Cả hai hook đều chạy sau khi tiến trình hoàn tất
  • Handler nhận đối tượng Argparse đã parse cùng trạng thái UI hiện tại của Gooey; nếu trả về trạng thái đã cập nhật thì UI có thể phản ánh thay đổi đó
  • Các handler được gắn khi tạo GooeyParser
parser = GooeyParser(
    on_success=my_success_handler,
    on_failure=my_failure_handler)
  • Để dùng, cần đăng ký sự kiện một cách tường minh
from gooey import Gooey, Events

@Gooey(use_events=[Events.ON_SUCCESS, Events.ON_ERROR])
def main():
    ...

Tiến trình và hiển thị thời gian

  • Gooey có thể đọc đầu ra tiến trình dạng văn bản sẵn có để điều khiển Progress Bar
  • Với trường hợp đơn giản, nó sẽ khớp chuỗi như Progress 83% bằng regex rồi chuyển thành tiến trình
@Gooey(progress_regex=r"^progress: (\d+)%$")
  • Với đầu ra phức tạp hơn, có thể dùng progress_expr để chuyển đổi kết quả khớp regex
@Gooey(progress_regex=r"^progress: (?P<current>\d+)/(?P<total>\d+)$",
       progress_expr="current / total * 100")
  • Nếu chỉ định hide_progress_msg=True, văn bản đầu ra khớp với tiến trình có thể bị ẩn khỏi console
  • Dùng timing_options có thể hiển thị thời gian đã trôi qua và thời gian còn lại
  • Hiển thị thời gian chỉ hoạt động khi dùng progress_regexprogress_expr

Icon và đóng gói

  • Gooey cung cấp sẵn 6 icon mặc định; có thể ghi đè bằng cách chỉ định thư mục ảnh tùy chỉnh qua tham số image_dir
  • Ảnh được tìm theo tên tệp, và các tên có thể ghi đè gồm
    • program_icon.png
    • success_icon.png
    • running_icon.png
    • loading_icon.gif
    • config_icon.png
    • error_icon.png
  • Việc đóng gói file thực thi có ví dụ sử dụng PyInstaller
  • Quy trình tóm tắt là đặt build.spec ở thư mục gốc ứng dụng, chỉnh các giá trị APPPNAME, name, pathex cho phù hợp với dự án rồi chạy
pyinstaller -F --windowed build.spec

1 bình luận

 
GN⁺ 2023-12-10
Ý kiến trên Hacker News
  • Ồ, đây là dự án của tôi mà ^_^ Sao nó lại lên đầu HN vậy?
    Trả lời ngắn gọn các bình luận liên quan đến argparse: Gooey giờ là một dự án khá cũ rồi, và vào thời điểm bắt đầu thì argparse là một lựa chọn vững chắc
    Ngày nay bản thân Gooey hoạt động bằng JSON và đã tách khỏi argparse, nhưng gần như không có ai tạo giao diện khác nên argparse vẫn là giao diện “chính thức” chủ yếu
    Một điểm thú vị là nó có thể gọi không chỉ Python mà cả bất kỳ tệp thực thi nào, nên khá hữu ích: https://chriskiehl.com/article/gooey-as-a-universal-frontend
    Về chuyện commit cuối cùng đã từ 2 năm trước: khi lớn tuổi hơn và ưu tiên thay đổi, rất khó tìm lý do để tiếp tục duy trì miễn phí một phần mềm ngách :( không biết có an ủi được gì không, nhưng tôi luôn cảm thấy có lỗi
    Kỳ lạ là khắp khu tôi sống có graffiti “GOOEY”, nên trông như một lời nhắc thường trực khiến tôi nhớ mãi đến issue tracker bị bỏ mặc haha

    • argparse vẫn là một lựa chọn khá tốt. Nó được dùng cực kỳ rộng rãi, tài liệu tốt và tương đối dễ
      Typer và Click cũng có tính khả dụng tốt, nhưng tôi thấy tài liệu kiểu “tutorial” của Typer khá khó tìm kiếm khi muốn có câu trả lời như Typer.App() nhận những đối số nào
      Chương trình tôi đang làm có cấu trúc để người dùng tự khởi động việc parse đối số, nên argparse rất phù hợp. Tôi muốn cung cấp cho người dùng một UI dạng văn bản như một lựa chọn, nhưng hình như Textualize cần Click; còn khi thử gắn trực tiếp Textual vào code để tạo UI thì tôi đã mất vài giờ mà thậm chí còn không bắt đầu được
    • Ý tưởng thật sự rất hay. Tôi thích giao diện tách rời khỏi API
      Ngày nay có quá nhiều bực bội vì không thể điều khiển ứng dụng bằng lập trình. Thành thật mà nói, tôi ước gì có luật rằng mọi tính năng của ứng dụng đều phải có API
    • Dự án tuyệt vời! Tôi có một thắc mắc: tại sao lại dump sys.argv ra một tệp cục bộ trong thư mục làm việc hiện tại? https://github.com/chriskiehl/Gooey/blob/be4b11b8f27f500e732...
      tmp.txt còn lâu mới là một tên duy nhất; tôi tò mò không biết mình có bỏ sót điều gì không
    • Phần “ngày nay bản thân Gooey hoạt động bằng JSON và đã tách khỏi argparse” thật hay
      Chỉ nhìn tiêu đề, trước khi bấm vào tôi đã nghĩ “chắc chắn nó phụ thuộc rất chặt vào argparse”, nên đây là một bất ngờ theo hướng tốt
      Tôi là fan nhiệt thành của getopt, vì tôi cho rằng sự tiện lợi của người dùng quan trọng hơn rất nhiều so với sự tiện lợi của nhà phát triển. Người dùng không cần phải quan tâm nhà phát triển chọn ngôn ngữ lập trình hay thư viện parse tùy chọn nào
      Nhiều thư viện như argparse, Click, flag của Go/kiểu X11 phá vỡ những quy ước đã ăn sâu vào trí nhớ cơ bắp tập thể tích lũy suốt nửa thế kỷ. Nhưng nếu có một lớp trung gian thì có vẻ có thể được cả đôi đường
    • Lý do Gooey rất cũ là vì nó đã bị bỏ mặc. Tôi không có ý chỉ trích, chỉ là thực tế là vậy
      Tệ hơn nữa là cũng chưa có phương án thay thế khả thi nào xuất hiện, và cả hai fork đều không có được traction
  • Cái này chẳng phải nên giới hạn là “dựa trên argparse” sao?
    argparse tốt cho các mục đích đơn giản, nhưng cũng có nhiều CLI dựa trên Click, và khá nhiều thư viện CLI phổ biến được xây trên Click. Cũng có các công cụ CLI Python không phải argparse hay Click, nhưng hai cái này có lẽ vẫn thuộc nhóm phổ biến nhất
    Đã xác nhận nó hoạt động với Click chưa? Hiện tại tôi chỉ thấy nội dung liên quan đến argparse. Nếu câu trả lời là không, thì cụm “gần như mọi” rõ ràng là sai, và tiêu đề chính xác hơn sẽ là “biến gần như mọi chương trình dòng lệnh Python dựa trên argparse thành ứng dụng GUI hoàn chỉnh”
    Cũng có chuyện commit có ý nghĩa gần nhất đã hơn 2 năm trước. Bản thân điều đó không xấu, nhưng nhìn số issue đang mở thì không tạo được nhiều niềm tin vào dự án
    Dù vậy đây vẫn là một dự án hay. Tôi muốn thấy nhiều thứ như thế này hơn. Như README nói, đây là công cụ nhân sức mạnh, để ai đó có thể tạo tự động hóa bằng CLI rồi dễ dàng chia sẻ cho những người văn phòng không thuộc mảng kỹ thuật. Nó tương tự vai trò Access từng làm cho cơ sở dữ liệu
    Giống như Access, khi quy mô hoặc độ phức tạp tăng lên thì sẽ đụng giới hạn, nhưng với nhu cầu văn phòng nhỏ thì có thể đủ “tốt vừa phải”

    • Tôi tò mò bạn thấy argparse thiếu điểm nào. Khuynh hướng của tôi là giảm thiểu phụ thuộc bên ngoài
    • Ở công ty cũ, tôi đã dùng đúng cho mục đích này. Tôi tự động hóa nhiều tác vụ và tạo công cụ cho nhóm; vì phần lớn họ không phải lập trình viên Python, tôi dùng Gooey để đặt một GUI đơn giản lên trên các script. Nó hoạt động rất tốt
    • Chính xác thì có gì không làm được bằng argparse?
  • Bài liên quan:
    Gooey: Turn almost any Python command line program into a GUI application - https://news.ycombinator.com/item?id=27490291 - tháng 6 năm 2021, 115 bình luận
    Gooey: Turn command line programs into GUI applications - https://news.ycombinator.com/item?id=8218785 - tháng 8 năm 2014, 74 bình luận

  • Sẽ thật tốt nếu hệ điều hành và shell có thể hiểu rõ hơn cách chạy chương trình mà không cần phụ thuộc vào một thư viện phân tích cú pháp cụ thể nào
    Sẽ thật tốt nếu các chương trình giao tiếp bằng định dạng JSON/proto có kiểu, và chỉ cần nhìn vào các kiểu đầu vào/đầu ra mong đợi là có thể có được cấu trúc lệnh shell, tự động hoàn thành, hoặc một GUI hoàn chỉnh
    Hiện tại, mức tốt nhất có vẻ chỉ là kiểu cắm ống hút một cách thận trọng. Mỗi chương trình phải xuất ra nhiều tệp tự động hoàn thành cho nhiều shell, phong cách flag khác nhau rất nhiều tùy chương trình và thư viện phân tích cú pháp, và tất nhiên cũng không có GUI

    • Giờ đã có một thứ gọi là PowerShell. Trả lời nghiêm túc hơn một chút thì có lẽ Plan 9 là hệ điều hành duy nhất từng thực sự thử làm điều như vậy
    • Ý bạn là một thứ như API CLI/trao đổi gRPC đa dụng có hỗ trợ native từ hệ điều hành? Cái đó có thể khá hay
      Tuy nhiên, vấn đề chính của gRPC có lẽ là nhiều lập trình viên, gồm cả tôi, cảm thấy nó hơi cồng kềnh hơn so với các giải pháp dùng tự nhiên trong ngôn ngữ
    • Nên thử dùng PowerShell. Về cơ bản, đó là hệ sinh thái .NET của Microsoft được nhào nặn thành dòng lệnh tương tác
      Tôi không chắc PowerShell có tận dụng trọn vẹn kiểu tĩnh làm cốt lõi hay không, nhưng khả năng truyền nhận object trên dòng lệnh thì gần như độc nhất
      Trên Linux, có thể kết hợp jc(https://github.com/kellyjonbrazil/jc) và jq(https://jqlang.github.io/jq/) để nối các lệnh dòng lệnh lại với nhau, nhưng so với tính năng tích hợp sẵn của PowerShell thì vẫn phải xử lý thêm hai bước
  • GUI đôi khi giống như món ăn an ủi. Vì bạn có thể cứ thế khám phá giao diện GUI mà không chịu gánh nặng nhận thức có thể phát sinh với một CLI ít dùng
    Hơi lạc đề một chút, nhưng vài tháng trước tôi biết đến trình soạn thảo CUDATEXT ở đây; nó cho phép dùng các phần tử GUI tùy ý như MENU, INPUTS thông qua một Python API dạng một tệp. Đây cũng là những phần tử mà chính trình soạn thảo sử dụng
    Hiện tôi đang dùng các phần tử GUI đơn giản đó để cấu hình và tạo blog ngay bên trong trình soạn thảo

  • Có thể xem thêm:
    “Textual: framework ứng dụng nhẹ cho Python. Tạo giao diện người dùng tinh vi bằng API Python đơn giản, và chạy app trong terminal cũng như trình duyệt web” https://github.com/textualize/textual/

  • Tôi muốn nói lời cảm ơn vì đã tạo ra phần mềm tuyệt vời này. Tôi thích Gooey và đã dùng nó khá nhiều trong nhiều chương trình
    Với tôi, nó hoàn toàn khớp với đúng tình huống khi một script Python đang làm việc quan trọng, và giờ cần làm cho người không biết lập trình cũng dùng được

  • Cái này làm tôi nhớ đến naked objects. Ý tưởng là chỉ cần định nghĩa vài annotation và theme cho một class Java thì toàn bộ GUI, hoặc một ứng dụng web frontend, sẽ được tạo ra
    Đó là một ý tưởng rất tuyệt, nhưng theo tôi biết thì cuối cùng nó không thực sự thành công

    • Django cũng có triết lý tương tự. Định nghĩa model là nó phản ánh ngay thành bảng cơ sở dữ liệu, và từ model đó có thể tự động tạo form
      Theo tôi, vấn đề là các mối quan tâm theo chiều dọc như presentation, domain và infrastructure bị ghép chặt với nhau. Khi cách biểu diễn trên màn hình và trong cơ sở dữ liệu của domain model còn đơn giản thì ổn
      Nhưng nếu muốn tạo một giao diện phức tạp với nhiều tính năng tiện lợi, các yêu cầu đó phải rò rỉ vào tầng domain. Ngược lại, nếu muốn tạo một domain model phức tạp, việc ép buộc các bất biến ở cấp ngôn ngữ là không thực tế. Vì bất kỳ đoạn code nào có tham chiếu Model đều có thể tùy ý động vào nó
  • Sẽ hay nếu có thứ làm theo chiều ngược lại

    • Sẽ thật tốt nếu có thể thiết lập parameter sweep bằng GUI dựa trên thông tin lấy từ argparse, rồi chuyển ngược nó thành một shell script chạy và lưu kết quả một cách phù hợp
    • Ý bạn là một trình soạn thảo WYSIWYG sinh ra CLI? Nghe khá hay, nhưng chắc chắn sẽ có một mức hạn chế nào đó. Tôi tò mò liệu có ai từng thử cách tiếp cận này chưa, nhưng không nghĩ ra ví dụ nào
  • Macintosh Programmer's Workshop ngày xưa, tức MPW, một shell dạng văn bản cho Mac OS thập niên 80–90, có một tính năng tương tự tên là Commando cho gần như mọi lệnh
    Thông tin Commando được lưu trong resource cmdo. Nếu hỗ trợ extended attribute không thất thường như hiện nay thì ngày nay cũng có thể làm thứ tương tự
    Tìm thử thì thấy A/UX cũng có Commando. Khi double-click một lệnh terminal trong Finder, một hộp Commando để chọn các tùy chọn CLI sẽ hiện ra, rồi lệnh được chạy trong cửa sổ shell. Ngày nay, nếu chạy lệnh terminal từ Finder thì nó chỉ chạy luôn trong cửa sổ shell mà không có đối số nào
    https://cohost.org/boredzo/post/804893-i-still-want-a-moder
    http://toastytech.com/guis/aux3.html