- 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à
DateChooser và TimeChooser 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
positional và optional
- 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'
)
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ó
name và items
- Mỗi mục menu luôn gồm
type và menuTitle
- 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
- 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_regex và progress_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
Ý 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ìargparselà một lựa chọn vững chắcNgà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ênargparsevẫn là giao diện “chính thức” chủ yếuMộ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
argparsevẫ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àoChươ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
argparserấ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 đượcNgà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
sys.argvra 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.txtcò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ôngargparse” thật hayChỉ 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ốtTô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àoNhiều thư viện như
argparse, Click,flagcủ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 đườngTệ 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?argparsetố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ảiargparsehay 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ênargparsethà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”
argparsethiếu điểm nào. Khuynh hướng của tôi là giảm thiểu phụ thuộc bên ngoàiargparse?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
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ữ
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ướcGUI đô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/
camply: https://juftin.com/camply/
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
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
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ợpMacintosh 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