3 poin oleh GN⁺ 2023-12-10 | 1 komentar | Bagikan ke WhatsApp
  • Gooey mengubah aplikasi konsol Python 3 menjadi aplikasi GUI yang mudah digunakan pengguna akhir, dan bekerja dengan menambahkan satu baris dekorator pada fungsi yang memiliki deklarasi argparse
  • Instalasi dasar dapat dilakukan dengan pip install Gooey; bila dekorator @Gooey digunakan bersama ArgumentParser, Gooey membaca argumen dan menyusun UI berbasis komponen WX
  • Saat pilihan widget bawaan kurang memadai, Anda dapat memasukkan GooeyParser sebagai pengganti ArgumentParser dan menentukan argumen widget untuk memilih widget kustom seperti FileChooser, DateChooser, PasswordField, dan Slider
  • Pengguna sasarannya bukan alat untuk developer yang langsung menangani CLI, melainkan skrip kantor “jalankan lalu selesai” atau alat untuk non-programmer; mendukung mode eksekusi advanced/basic/tanpa konfigurasi, menu, tampilan progres, internasionalisasi, penggantian ikon, dan packaging
  • Validasi dinamis dan event siklus hidup ditandai sebagai fitur eksperimental; optparse saat ini tidak didukung, dan diasumsikan menggunakan kode berbasis ArgumentParser serta langganan event opsional

Cara mengubah program konsol menjadi GUI

  • Gooey mengubah aplikasi konsol menjadi aplikasi GUI yang mudah ditangani pengguna akhir
  • Cara penggunaan intinya adalah menambahkan dekorator @Gooey pada fungsi yang berisi deklarasi argparse
from gooey import Gooey

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

# rest of code
  • Gaya dan perilaku dapat disesuaikan melalui argumen dekorator
    • advanced: apakah menampilkan layar pengaturan lanjutan
    • language: memilih terjemahan berbasis JSON
    • auto_start: melewati layar pengaturan dan langsung menjalankan
    • target: menentukan perintah yang akan dijalankan sebagai subproses
    • program_name, program_description: nama dan deskripsi yang ditampilkan di GUI
    • default_size: ukuran awal GUI
    • dump_build_config, load_build_config: menyimpan/memuat JSON konfigurasi build Gooey
    • monospace_display: menggunakan font monospace pada layar output

Instalasi dan contoh

  • Cara instalasi paling mudah adalah pip
pip install Gooey
  • Anda juga dapat melakukan clone repositori lalu menjalankan setup.py untuk instalasi
git clone https://github.com/chriskiehl/Gooey.git
python setup.py install
  • Skrip contoh yang sudah disiapkan dapat diperoleh dari repositori Gooey Examples
  • Repositori contoh disediakan untuk menjelajahi berbagai layout, widget, dan fitur Gooey

Mengapa dibutuhkan

  • Gooey dibuat untuk mengurangi masalah menampilkan command prompt kepada pengguna yang tidak terbiasa dengannya
  • Agar sebuah program dapat melakukan satu atau lebih tugas, program tersebut harus menerima opsi; sebelumnya, developer harus membuat GUI sendiri atau menjelaskan cara meneruskan argumen ke aplikasi konsol
  • Gooey memungkinkan developer membuat program yang dapat dikonfigurasi dengan cara yang familier, sekaligus menyediakan tampilan dan interaksi melalui GUI

Pengguna yang cocok dan kasus yang kurang cocok

  • Gooey mungkin kurang cocok untuk utilitas bagi diri sendiri atau programmer lain, atau alat yang menghasilkan output untuk di-pipe ke aplikasi konsol lain
  • Cocok untuk skrip eksekusi kantor, alat yang memindahkan data dari titik A ke B, dan program untuk non-programmer
  • Tujuannya adalah membuat aplikasi yang kompleks sekaligus mendapatkan sisi GUI tanpa biaya tambahan

Cara kerja internal dan pemetaan argparse

  • Gooey mem-parse referensi ArgumentParser dari skrip Python saat runtime
  • optparse saat ini tidak didukung
  • Argumen yang diekstrak diberi component type berdasarkan action yang disediakan dan digunakan untuk menyusun GUI
  • ArgumentParser._actions pada dasarnya dipetakan ke komponen WX berikut
    • store: TextCtrl
    • store_const, store_true, store_False, version: CheckBox
    • append: TextCtrl
    • count: DropDown
    • Mutually Exclusive Group: RadioGroup
    • choice: DropDown

GooeyParser dan widget kustom

  • Jika pilihan widget bawaan tidak cukup, Anda dapat menggunakan GooeyParser, pengganti drop-in untuk ArgumentParser
  • GooeyParser menyediakan argumen keyword tambahan widget untuk menentukan nama komponen yang akan ditampilkan
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")
  • Widget kustom yang didukung mencakup
    • DirChooser, FileChooser, MultiFileChooser
    • FileSaver, MultiFileSaver
    • DateChooser, TimeChooser
    • PasswordField
    • Listbox
    • BlockCheckbox
    • ColourChooser
    • FilterableDropdown
    • IntegerField, DecimalField
    • Slider
  • Nilai yang diteruskan DateChooser dan TimeChooser ke aplikasi selalu dalam ISO format, sementara sebagian GUI dapat menampilkan nilai terlokalisasi sesuai pengaturan pengguna akhir
  • BlockCheckbox memindahkan blok teks ke posisi biasa agar lebih enak dilihat dibanding checkbox inline bawaan saat ada teks bantuan yang panjang, dan menampilkan block_label singkat di samping kontrol

Internasionalisasi

  • Gooey memilih bahasa tampilan melalui argumen language pada dekorator
@Gooey(language='russian')
def main():
    ...
  • Semua teks program disimpan dalam file JSON eksternal
  • Dukungan bahasa baru dilakukan dengan menambahkan key/value ke direktori gooey/languages/
  • Saat ini tersedia lebih dari 18 terjemahan secara bawaan

Pengaturan global dan konfigurasi UI

  • Tampilan dan perilaku umum Gooey disesuaikan melalui argumen dekorator
  • Pengaturan utama mencakup
    • encoding: encoding karakter tampilan, nilai bawaan utf-8
    • advanced: memilih layar pengaturan penuh atau layar yang disederhanakan
    • auto_start: langsung berjalan tanpa konfigurasi
    • target: menentukan cara Gooey menjalankan ulang dirinya sendiri
    • suppress_gooey_flag: mencegah injeksi parameter CLI tambahan saat menggunakan target kustom
    • fullscreen: mulai dalam layar penuh
    • image_dir: direktori gambar/ikon kustom
    • language_dir: direktori file bahasa kustom
    • disable_stop_button, show_stop_warning: mengontrol tombol stop dan peringatan saat berjalan
    • show_success_modal, show_failure_modal: apakah menampilkan modal ringkasan berhasil/gagal
    • run_validators: apakah menjalankan validasi sebelum memanggil program
    • progress_regex, progress_expr: parsing dan transformasi teks progres
    • navigation: TABBED atau SIDEBAR
    • body_bg_color, header_bg_color, footer_bg_color, sidebar_bg_color: pengaturan warna
    • terminal_font_family, terminal_font_size, terminal_font_color: pengaturan font tampilan terminal
    • menus: grup dan item menu kustom
    • clear_before_run: menghapus output sebelumnya saat dijalankan ulang

Layout dan mode eksekusi

  • Gooey secara default membagi input menjadi dua grup: positional dan optional
  • Dengan add_argument_group() dari argparse, input dapat dikelompokkan secara logis dan layout tiap grup dapat disesuaikan
parser = ArgumentParser()
search_group = parser.add_argument_group(
    "Search Options",
    "Customize the search options"
)
search_group.add_argument(
    '--query',
    help='Base search string'
)
  • Opsi layout penuh yang didukung mencakup show_sidebar=True, show_sidebar=False, navigation='TABBED', dan tabbed_groups=True
  • Advanced

    • Layar default adalah layar pengaturan full/advanced
    • Untuk sebagian besar aplikasi, layout datar yang sesuai dengan struktur CLI cocok digunakan
    • Untuk CLI yang terdiri dari beberapa jalur atau kombinasi alat-alat kecil, layout kolom cocok digunakan
    • Layout kolom menampilkan jalur utama di kolom kiri dan argumen terkait di sisi kanan
    • Layout saat ini tidak dapat ditentukan secara eksplisit melalui parameter, dan dikonfigurasi berdasarkan ada tidaknya subparsers dalam kode
  • Basic

    • Mengatur advanced=False akan beralih ke tampilan dasar
    • Cocok ketika pengguna sudah terbiasa dengan aplikasi konsol tetapi menginginkan layar yang lebih rapi daripada terminal sederhana
    @gooey(advanced=False)
    def main():
    
    # rest of code
    
  • No Config

    • Mengatur auto_start=True akan langsung berpindah ke area tampilan tanpa layar pengaturan dan menjalankan program host
    • Digunakan untuk memperbaiki tampilan skrip kecil sekali pakai
    @Gooey(auto_start=True)
    def main():
        ...
    

Fitur menu

  • Mulai Gooey 1.0.2, Menu Bar dapat ditambahkan di bagian atas
  • Menu ditentukan sebagai daftar map berbentuk @Gooey(menu=[{}, {}, ...])
  • Setiap grup menu memiliki name dan items
  • Setiap item menu selalu memuat type dan menuTitle
  • Tipe item menu yang didukung adalah
    • AboutDialog: menampilkan informasi program seperti nama, versi, dan lisensi
    • MessageDialog: menampilkan pesan informatif kepada pengguna
    • Link: membuka URL yang ditentukan di browser default
    • HtmlDialog: menampilkan dialog menggunakan subset HTML terbatas

Validasi dinamis

  • Dynamic Validation adalah fitur eksperimental dan API-nya dapat berubah atau dihapus
  • Gooey secara opsional dapat melakukan pra-validasi sebelum meneruskan input pengguna ke program
  • Fitur ini memanfaatkan parameter type yang dapat digunakan pada sebagian besar tipe argumen 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!")
  • Validasi tidak dijalankan secara default
  • Untuk mengaktifkannya, Anda harus berlangganan event VALIDATE_FORM
from gooey import Gooey, Events

@Gooey(use_events=[Events.VALIDATE_FORM])
def main():
    ...
  • Karena fitur ini menggunakan Monkey Patching yang kuat secara internal, saat ini fiturnya bersifat opt-in

Event siklus hidup dan kontrol UI

  • Mulai Gooey 1.2.0, hook siklus hidup diekspos ke program
  • Fitur ini juga eksperimental dan API-nya dapat berubah atau dihapus
  • Saat ini ada dua hook utama
    • on_success
    • on_error
  • Kedua hook dijalankan setelah proses selesai
  • Handler menerima objek Argparse yang sudah di-parse dan status UI Gooey saat ini; jika mengembalikan status yang diperbarui, status tersebut dapat diterapkan ke UI
  • Handler dihubungkan saat membuat GooeyParser
parser = GooeyParser(
    on_success=my_success_handler,
    on_failure=my_failure_handler)
  • Untuk menggunakannya, Anda harus berlangganan event secara eksplisit
from gooey import Gooey, Events

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

Progres dan tampilan waktu

  • Gooey dapat membaca output progres teks yang sudah ada untuk menggerakkan Progress Bar
  • Dalam kasus sederhana, string seperti Progress 83% dicocokkan dengan regex dan dikonversi menjadi progres
@Gooey(progress_regex=r"^progress: (\d+)%$")
  • Output yang lebih kompleks dapat ditransformasikan dari hasil pencocokan regex dengan progress_expr
@Gooey(progress_regex=r"^progress: (?P<current>\d+)/(?P<total>\d+)$",
       progress_expr="current / total * 100")
  • Dengan menentukan hide_progress_msg=True, output teks yang cocok dengan progres dapat disembunyikan dari konsol
  • Dengan timing_options, waktu berlalu dan sisa waktu dapat ditampilkan
  • Tampilan waktu hanya bekerja saat menggunakan progress_regex dan progress_expr

Ikon dan packaging

  • Gooey menyediakan 6 ikon bawaan, dan Anda dapat menimpanya dengan menentukan direktori gambar kustom melalui argumen image_dir
  • Gambar dicari berdasarkan nama file, dan nama file yang dapat ditimpa adalah
    • program_icon.png
    • success_icon.png
    • running_icon.png
    • loading_icon.gif
    • config_icon.png
    • error_icon.png
  • Packaging executable menyediakan contoh penggunaan PyInstaller
  • Ringkasan prosedurnya adalah menaruh build.spec di root aplikasi, menyesuaikan nilai APPPNAME, name, dan pathex dengan proyek, lalu menjalankannya
pyinstaller -F --windowed build.spec

1 komentar

 
GN⁺ 2023-12-10
Komentar Hacker News
  • Eh, ini proyek saya ^_^ kenapa bisa naik ke puncak HN?
    Menjawab singkat komentar terkait argparse, Gooey sekarang sudah menjadi proyek yang cukup tua, dan saat dimulai dulu argparse adalah pilihan yang solid
    Belakangan ini Gooey sendiri berjalan dengan JSON dan terpisah dari argparse, tetapi hampir tidak ada yang membuat antarmuka lain, jadi argparse masih tetap menjadi antarmuka “resmi” utama
    Yang menarik, ini cukup berguna karena bisa memanggil bukan hanya Python tetapi juga berkas eksekusi arbitrer: https://chriskiehl.com/article/gooey-as-a-universal-frontend
    Soal komentar bahwa commit terakhirnya 2 tahun lalu, ketika usia bertambah dan prioritas berubah, makin sulit menemukan alasan untuk terus memelihara perangkat lunak niche secara gratis :( entah ini menghibur atau tidak, tapi saya selalu merasa bersalah
    Anehnya, di berbagai sudut lingkungan tempat saya tinggal ada grafiti bertuliskan “GOOEY”, jadi terasa seperti pengingat permanen yang terus membuat saya teringat pada issue tracker yang terbengkalai haha

    • argparse masih merupakan pilihan yang cukup bagus. Sudah sangat luas dipakai, dokumentasinya baik, dan relatif mudah
      Typer dan Click juga enak dipakai, tetapi dokumentasi bergaya “tutorial” Typer terasa cukup sulit dicari kalau ingin menemukan jawaban seperti argumen apa saja yang diterima Typer.App()
      Program yang sedang saya kerjakan memakai struktur di mana pengguna sendiri yang memulai parsing argumen, jadi argparse cocok. Saya ingin memberi pengguna opsi UI berbasis teks, tetapi sepertinya Textualize membutuhkan Click, dan saat mencoba menempelkan Textual langsung ke kode untuk membuat UI pun saya sudah menghabiskan beberapa jam tanpa berhasil mulai sama sekali
    • Ini ide yang sangat keren. Saya suka antarmuka yang terpisah dari API
      Akhir-akhir ini terlalu banyak hal yang membuat frustrasi karena aplikasi tidak bisa dikendalikan secara terprogram. Sejujurnya saya berharap ada hukum yang mewajibkan setiap fungsi aplikasi memiliki API
    • Proyek yang keren! Saya penasaran, kenapa sys.argv di-dump ke berkas lokal di direktori kerja saat ini? https://github.com/chriskiehl/Gooey/blob/be4b11b8f27f500e732...
      tmp.txt rasanya jauh dari nama yang unik, jadi saya penasaran apakah ada sesuatu yang saya lewatkan
    • Bagian “belakangan ini Gooey sendiri berjalan dengan JSON dan terpisah dari argparse” itu keren
      Sebelum klik, hanya dari judulnya saya sempat berpikir “pasti sangat bergantung pada argparse”, jadi ini kejutan yang menyenangkan
      Saya penggemar berat getopt, karena menurut saya kenyamanan pengguna jauh lebih penting daripada kenyamanan pengembang. Pengguna tidak seharusnya perlu peduli bahasa pemrograman atau library parsing opsi apa yang dipilih pengembang
      argparse, Click, gaya flag/X11 milik Go, dan banyak library lain merusak konvensi yang sudah tertanam dalam memori otot kolektif selama setengah abad. Tetapi jika ada lapisan perantara, sepertinya kita bisa mendapat dua-duanya
    • Gooey sudah sangat tua karena memang dibiarkan begitu saja. Bukan bermaksud menyalahkan, hanya memang itulah kenyataannya
      Yang lebih buruk, belum muncul alternatif yang benar-benar layak untuk menggantikannya, dan dari dua fork yang ada pun tidak ada yang mendapatkan traction
  • Bukankah ini seharusnya dibatasi sebagai “berbasis argparse”?
    argparse bagus untuk penggunaan sederhana, tetapi ada banyak CLI berbasis Click, dan cukup banyak library CLI populer dibangun di atas Click. Ada juga alat CLI Python yang bukan argparse maupun Click, tetapi keduanya mungkin yang paling populer
    Apakah sudah dipastikan bekerja juga dengan Click? Saat ini yang terlihat hanya hal-hal terkait argparse. Kalau jawabannya tidak, maka ungkapan “hampir semua” jelas tidak benar, dan judul yang lebih akurat adalah “mengubah hampir semua program command line Python berbasis argparse menjadi aplikasi GUI penuh”
    Ada juga fakta bahwa commit bermakna terakhir sudah lebih dari 2 tahun lalu. Itu sendiri bukan hal buruk, tetapi melihat jumlah issue yang terbuka, hal itu tidak terlalu menumbuhkan kepercayaan pada proyek ini
    Meski begitu, ini proyek yang keren. Saya ingin melihat lebih banyak hal seperti ini. Seperti yang dikatakan README, ini adalah alat pengganda tenaga, sehingga seseorang bisa membuat otomasi lewat CLI lalu membagikannya dengan mudah kepada staf kantor nonteknis. Mirip dengan peran Access untuk basis data
    Seperti Access, saat skala atau kompleksitas meningkat, ini akan menemui batasnya, tetapi untuk kebutuhan kantor kecil, ini bisa cukup “lumayan”

    • Saya penasaran kekurangan apa yang Anda lihat pada argparse. Kecenderungan saya adalah ke arah meminimalkan dependensi eksternal
    • Di tempat kerja sebelumnya saya memakai ini tepat untuk tujuan seperti itu. Saya mengotomatiskan banyak pekerjaan dan membuat alat untuk tim, tetapi kebanyakan bukan programmer Python, jadi saya menambahkan GUI sederhana di atas skrip dengan Gooey. Hasilnya bekerja sangat baik
    • Tepatnya apa yang tidak bisa dilakukan dengan argparse?
  • Tulisan terkait:
    Gooey: Turn almost any Python command line program into a GUI application - https://news.ycombinator.com/item?id=27490291 - Juni 2021, 115 komentar
    Gooey: Turn command line programs into GUI applications - https://news.ycombinator.com/item?id=8218785 - Agustus 2014, 74 komentar

  • Akan bagus kalau sistem operasi dan shell bisa lebih memahami cara menjalankan program tanpa bergantung pada pustaka parsing tertentu
    Akan bagus kalau program bisa berkomunikasi dalam format JSON/proto bertipe, dan hanya dengan melihat tipe input/output yang diharapkan, kita bisa mendapatkan struktur perintah shell, auto-complete, atau bahkan GUI yang lengkap
    Saat ini sepertinya yang terbaik hanyalah solusi tambal sulam yang dibuat dengan hati-hati. Setiap program harus mengekspor beberapa file auto-complete untuk berbagai shell, gaya flag sangat berbeda antara program dan pustaka parsing, dan tentu saja tidak ada GUI

    • Sekarang ada yang namanya PowerShell. Kalau mau menjawab lebih serius, mungkin Plan 9 adalah satu-satunya sistem operasi yang benar-benar pernah mencoba hal seperti ini
    • Maksudnya sesuatu seperti API pertukaran gRPC/CLI serbaguna dengan dukungan native dari sistem operasi? Itu bisa jadi cukup keren
      Hanya saja masalah utama gRPC mungkin adalah banyak pengembang, termasuk saya, merasa ia agak merepotkan dibanding solusi yang terasa alami dipakai di dalam bahasa pemrograman
    • Coba pakai PowerShell. Pada dasarnya itu adalah ekosistem .NET Microsoft yang diwujudkan menjadi command line interaktif
      Saya tidak yakin apakah PowerShell benar-benar memanfaatkan semua kemampuan static typing yang menjadi inti darinya, tetapi kemampuannya mengoper objek lewat command line hampir tidak ada tandingannya
      Di Linux, kita bisa merangkai command line dengan menggabungkan jc(https://github.com/kellyjonbrazil/jc) dan jq(https://jqlang.github.io/jq/), tetapi dibanding kemampuan bawaan PowerShell, itu tetap menambah dua langkah lagi
  • GUI kadang terasa seperti comfort food. Karena kita bisa sekadar menjelajahi antarmuka GUI tanpa beban kognitif yang bisa muncul dari CLI yang jarang dipakai
    Sedikit topik lain, beberapa bulan lalu saya menemukan editor CUDATEXT di sini, dan editor itu memungkinkan penggunaan elemen GUI sewenang-wenang seperti MENU, INPUTS, dan lain-lain melalui API Python satu berkas. Elemen-elemen ini juga dipakai oleh editornya sendiri
    Sekarang saya memakai elemen GUI sederhana seperti itu untuk melakukan konfigurasi dan membuat blog langsung dari dalam editor

  • Layak juga dilihat:
    “Textual: framework aplikasi ringan untuk Python. Bangun antarmuka pengguna yang canggih dengan API Python yang sederhana, dan jalankan aplikasi di terminal maupun browser web” https://github.com/textualize/textual/

  • Saya hanya ingin mengucapkan terima kasih karena telah membuat perangkat lunak yang hebat ini. Saya menyukai Gooey dan sudah sering memakainya di berbagai program
    Bagi saya ini sangat pas untuk area ketika skrip Python melakukan pekerjaan penting, dan sekarang perlu dibuat agar bisa dipakai juga oleh non-programmer

  • Ini mengingatkan saya pada naked objects. Idenya adalah cukup mendefinisikan beberapa anotasi dan tema pada kelas Java, lalu seluruh GUI atau aplikasi frontend web akan dihasilkan
    Itu ide yang sangat keren, tetapi setahu saya pada akhirnya tidak benar-benar berhasil

    • Django juga punya filosofi yang mirip. Anda mendefinisikan model, lalu itu langsung tercermin ke tabel database, dan form bisa dibuat otomatis dari model tersebut
      Menurut saya masalahnya adalah concern vertikal seperti presentasi, domain, dan infrastruktur menjadi saling terikat. Jika representasi layar dan representasi database dari model domain itu sederhana, ini masih baik-baik saja
      Tetapi kalau ingin membuat antarmuka kompleks dengan banyak fitur kemudahan, kebutuhan itu akan bocor masuk ke lapisan domain. Sebaliknya, kalau ingin membuat model domain yang kompleks, menjadi tidak realistis untuk menegakkan invariant di level bahasa. Karena kode apa pun yang memegang referensi Model bisa mengutak-atiknya sesuka hati
  • Akan menarik juga kalau ada yang melakukan kebalikannya

    • Akan bagus kalau kita bisa menyiapkan parameter sweep lewat GUI berdasarkan informasi yang diambil dari argparse, lalu mengubahnya kembali menjadi shell script yang menjalankan dan menyimpan hasilnya dengan benar
    • Maksudnya editor WYSIWYG yang menghasilkan CLI? Kedengarannya cukup keren, tetapi tampaknya pasti akan ada tingkat keterbatasan tertentu. Saya penasaran apakah ada yang pernah mencoba pendekatan seperti itu, tetapi saya tidak teringat contoh apa pun
  • Dulu Macintosh Programmer's Workshop, yaitu shell berbasis teks untuk Mac OS pada era 80-an hingga 90-an, memiliki fitur serupa bernama Commando untuk hampir semua perintah
    Informasi Commando disimpan dalam resource cmdo. Jika dukungan extended attributes tidak begitu naik turun, hal serupa mungkin masih bisa dilakukan sampai sekarang
    Setelah saya cek, ternyata A/UX juga memiliki Commando. Saat Anda mengeklik ganda perintah terminal dari Finder, kotak Commando akan muncul untuk memilih opsi CLI, lalu setelah itu perintah dijalankan di jendela shell. Finder modern kalau diminta menjalankan perintah terminal biasanya hanya menjalankannya di jendela shell tanpa argumen
    https://cohost.org/boredzo/post/804893-i-still-want-a-moder
    http://toastytech.com/guis/aux3.html