使用 PySimpleGUI 輕鬆為程序和腳本增加 GUI | Linux 中國

2021-12-11 Linux

五分鐘創建定製 GUI。

對於 .exe 類型的程序文件,我們可以通過雙擊滑鼠左鍵打開;但對於 .py 類型的 Python 程序,幾乎不會有人嘗試同樣的操作。對於一個(非程式設計師類型的)典型用戶,他們雙擊打開 .exe 文件時預期彈出一個可以交互的窗體。基於 Tkinter,可以通過標準 Python 安裝standard Python installations的方式提供 GUI,但很多程序都不太可能這樣做。

如果打開 Python 程序並進入 GUI 界面變得如此容易,以至於真正的初學者也可以掌握,會怎樣呢?會有人感興趣並使用嗎?這個問題不好回答,因為直到今天創建自定義 GUI 布局仍不是件容易的事情。

在為程序或腳本增加 GUI 這件事上,似乎存在能力的「錯配」。(缺乏這方面能力的)真正的初學者被迫只能使用命令行方式,而很多(具備這方面能力的)高級程式設計師卻不願意花時間創建一個 Tkinter GUI。

GUI 框架

Python 的 GUI 框架並不少,其中 Tkinter,wxPython,Qt 和 Kivy 是幾種比較主流的框架。此外,還有不少在上述框架基礎上封裝的簡化框架,例如 EasyGUI,PyGUI 和 Pyforms 等。

但問題在於,對於初學者(這裡是指編程經驗不超過 6 個月的用戶)而言,即使是最簡單的主流框架,他們也無從下手;他們也可以選擇封裝過的(簡化)框架,但仍難以甚至無法創建自定義 GUI 布局layout。即便學會了某種(簡化)框架,也需要編寫連篇累牘的代碼。

PySimpleGUI[1] 嘗試解決上述 GUI 難題,它提供了一種簡單明了、易於理解、方便自定義的 GUI 接口。如果使用 PySimpleGUI,很多複雜的 GUI 也僅需不到 20 行代碼。

秘訣

PySimpleGUI 極為適合初學者的秘訣在於,它已經包含了絕大多數原本需要用戶編寫的代碼。PySimpleGUI 會處理按鈕回調callback,無需用戶編寫代碼。對於初學者,在幾周內掌握函數的概念已經不容易了,要求其理解回調函數似乎有些強人所難。

在大部分 GUI 框架中,布局 GUI 小部件widgets通常需要寫一些代碼,每個小部件至少 1-2 行。PySimpleGUI 使用了 「auto-packer」 技術,可以自動創建布局。因而,布局 GUI 窗口不再需要 pack 或 grid 系統。

(LCTT 譯註:這裡提到的 pack 和 grid 都是 Tkinter 的布局管理器,另外一種叫做 place 。)

最後,PySimpleGUI 框架編寫中有效地利用了 Python 語言特性,降低用戶代碼量並簡化 GUI 數據返回的方式。在窗體form布局中創建小部件時,小部件會被部署到對應的布局中,無需額外的代碼。

GUI 是什麼?

絕大多數 GUI 只完成一件事情:收集用戶數據並返回。在程式設計師看來,可以歸納為如下的函數調用:

button, values = GUI_Display(gui_layout)

絕大多數 GUI 支持的用戶行為包括滑鼠點擊(例如,「確認」,「取消」,「保存」,「是」和「否」等)和內容輸入。GUI 本質上可以歸結為一行代碼。

這也正是 PySimpleGUI (的簡單 GUI 模式)的工作原理。當執行命令顯示 GUI 後,除非點擊滑鼠關閉窗體,否則不會執行任何代碼。

當然還有更複雜的 GUI,其中滑鼠點擊後窗口並不關閉;例如,機器人的遠程控制界面,聊天窗口等。這類複雜的窗體也可以用 PySimpleGUI 創建。

快速創建 GUI

PySimpleGUI 什麼時候有用呢?顯然,是你需要 GUI 的時候。僅需不超過 5 分鐘,就可以讓你創建並嘗試 GUI。最便捷的 GUI 創建方式就是從 PySimpleGUI 經典實例[2]中拷貝一份代碼。具體操作流程如下:

下面我們看一下書中的第一個經典實例recipe:

import PySimpleGUI as sg

# Very basic form.  Return values as a list

form = sg.FlexForm('Simple data entry form')  # begin with a blank form

layout = [

          [sg.Text('Please enter your Name, Address, Phone')],

          [sg.Text('Name', size=(15, 1)), sg.InputText('name')],

          [sg.Text('Address', size=(15, 1)), sg.InputText('address')],

          [sg.Text('Phone', size=(15, 1)), sg.InputText('phone')],

          [sg.Submit(), sg.Cancel()]

         ]

button, values = form.LayoutAndRead(layout)

print(button, values[0], values[1], values[2])

運行後會打開一個大小適中的窗體。

如果你只是想收集一些字符串類型的值,拷貝上述經典實例中的代碼,稍作修改即可滿足你的需求。

你甚至可以只用 5 行代碼創建一個自定義 GUI 布局。

import PySimpleGUI as sg

form = sg.FlexForm('My first GUI')

layout = [ [sg.Text('Enter your name'), sg.InputText()],

           [sg.OK()] ]

button, (name,) = form.LayoutAndRead(layout)

5 分鐘內創建一個自定義 GUI

在簡單布局的基礎上,通過修改經典實例中的代碼,5 分鐘內即可使用 PySimpleGUI 創建自定義布局。

在 PySimpleGUI 中,小部件widgets被稱為元素elements。元素的名稱與編碼中使用的名稱保持一致。

(LCTT 譯註:Tkinter 中使用小部件這個詞)

核心元素

Text

InputText

Multiline

InputCombo

Listbox

Radio

Checkbox

Spin

Output

SimpleButton

RealtimeButton

ReadFormButton

ProgressBar

Image

Slider

Column

元素簡寫

PySimpleGUI 還包含兩種元素簡寫方式。一種是元素類型名稱簡寫,例如 T 用作 Text 的簡寫;另一種是元素參數被配置了默認值,你可以無需指定所有參數,例如 Submit 按鈕默認的文本就是 「Submit」。

T = Text

Txt = Text

In = InputText

Input = IntputText

Combo = InputCombo

DropDown = InputCombo

Drop = InputCombo

(LCTT 譯註:第一種簡寫就是 Python 類的別名,第二種簡寫是在返回元素對象的 Python 函數定義時指定了參數的默認值)

按鈕簡寫

一些通用按鈕具有簡寫實現,包括:

FolderBrowse

FileBrowse

FileSaveAs

Save

Submit

OK

Ok (LCTT 譯註:這裡 `k` 是小寫)

Cancel

Quit

Exit

Yes

No

此外,還有通用按鈕功能對應的簡寫:

SimpleButton

ReadFormButton

RealtimeButton

(LCTT 譯註:其實就是返回 Button 類實例的函數)

上面就是 PySimpleGUI 支持的全部元素。如果不在上述列表之中,就不會在你的窗口布局中生效。

(LCTT 譯註:上述都是 PySimpleGUI 的類名、類別名或返回實例的函數,自然只能使用列表內的。)

GUI 設計模式

對於 GUI 程序,創建並展示窗口的調用大同小異,差異在於元素的布局。

設計模式代碼與上面的例子基本一致,只是移除了布局:

import PySimpleGUI as sg

form = sg.FlexForm('Simple data entry form')

# Define your form here (it's a list of lists)

button, values = form.LayoutAndRead(layout)

(LCTT 譯註:這段代碼無法運行,只是為了說明每個程序都會用到的設計模式。)

對於絕大多數 GUI,編碼流程如下:

上述流程與 PySimpleGUI 設計模式部分的代碼一一對應。

GUI 布局

要創建自定義 GUI,首先要將窗體分割成多個行,因為窗體是一行一行定義的。然後,在每一行中從左到右依次放置元素。

我們得到的就是一個「列表的列表」,類似如下:

layout = [  [Text('Row 1')],

            [Text('Row 2'), Checkbox('Checkbox 1', OK()), Checkbox('Checkbox 2'), OK()] ]

上述布局對應的效果如下:

展示 GUI

當你完成布局、拷貝完用於創建和展示窗體的代碼後,下一步就是展示窗體並收集用戶數據。

下面這行代碼用於展示窗體並返回收集的數據:

button, values = form.LayoutAndRead(layout)

窗體返回的結果由兩部分組成:一部分是被點擊按鈕的名稱,另一部分是一個列表,包含所有用戶輸入窗體的值。

在這個例子中,窗體顯示後用戶直接點擊 「OK」 按鈕,返回的結果如下:

button == 'OK'

values == [False, False]

Checkbox 類型元素返回 True 或 False 類型的值。由於默認處於未選中狀態,兩個元素的值都是 False。

顯示元素的值

一旦從 GUI 獲取返回值,檢查返回變量中的值是個不錯的想法。與其使用 print 語句進行列印,我們不妨堅持使用 GUI 並在一個窗口中輸出這些值。

(LCTT 譯註:考慮使用的是 Python 3 版本,print 應該是函數而不是語句。)

在 PySimpleGUI 中,有多種消息框可供選取。傳遞給消息框(函數)的數據會被顯示在消息框中;函數可以接受任意數目的參數,你可以輕鬆的將所有要查看的變量展示出來。

在 PySimpleGUI 中,最常用的消息框是 MsgBox。要展示上面例子中的數據,只需編寫一行代碼:

MsgBox('The GUI returned:', button, values)

整合

好了,你已經了解了基礎知識,讓我們創建一個包含儘可能多 PySimpleGUI 元素的窗體吧!此外,為了更好的感觀效果,我們將採用綠色/棕褐色的配色方案。

import PySimpleGUI as sg

sg.ChangeLookAndFeel('GreenTan')

form = sg.FlexForm('Everything bagel', default_element_size=(40, 1))

column1 = [[sg.Text('Column 1', background_color='#d3dfda', justification='center', size=(10,1))],

           [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 1')],

           [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2')],

           [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 3')]]

layout = [

    [sg.Text('All graphic widgets in one form!', size=(30, 1), font=("Helvetica", 25))],

    [sg.Text('Here is some text.... and a place to enter text')],

    [sg.InputText('This is my text')],

    [sg.Checkbox('My first checkbox!'), sg.Checkbox('My second checkbox!', default=True)],

    [sg.Radio('My first Radio!     ', "RADIO1", default=True), sg.Radio('My second Radio!', "RADIO1")],

    [sg.Multiline(default_text='This is the default Text should you decide not to type anything', size=(35, 3)),

     sg.Multiline(default_text='A second multi-line', size=(35, 3))],

    [sg.InputCombo(('Combobox 1', 'Combobox 2'), size=(20, 3)),

     sg.Slider(range=(1, 100), orientation='h', size=(34, 20), default_value=85)],

    [sg.Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3'), size=(30, 3)),

     sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=25),

     sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=75),

     sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=10),

     sg.Column(column1, background_color='#d3dfda')],

    [sg.Text('_'  * 80)],

    [sg.Text('Choose A Folder', size=(35, 1))],

    [sg.Text('Your Folder', size=(15, 1), auto_size_text=False, justification='right'),

     sg.InputText('Default Folder'), sg.FolderBrowse()],

    [sg.Submit(), sg.Cancel()]

     ]

button, values = form.LayoutAndRead(layout)

sg.MsgBox(button, values)

看上面要寫不少代碼,但如果你試著直接使用 Tkinter 框架實現同樣的 GUI,你很快就會發現 PySimpleGUI 版本的代碼是多麼的簡潔。

代碼的最後一行打開了一個消息框,效果如下:

消息框函數中的每一個參數的內容都會被列印到單獨的行中。本例的消息框中包含兩行,其中第二行非常長而且包含列表嵌套。

建議花一點時間將上述結果與 GUI 中的元素一一比對,這樣可以更好的理解這些結果是如何產生的。

為你的程序或腳本添加 GUI

如果你有一個命令行方式使用的腳本,添加 GUI 不一定意味著完全放棄該腳本。一種簡單的方案如下:如果腳本不需要命令行參數,那麼可以直接使用 GUI 調用該腳本;反之,就按原來的方式運行腳本。

僅需類似如下的邏輯:

if len(sys.argv) == 1:

        # collect arguments from GUI

else:

    # collect arguements from sys.argv

創建並運行 GUI 最便捷的方式就是從 PySimpleGUI 經典實例[2]中拷貝一份代碼並修改。

快來試試吧!給你一直疲於手動執行的腳本增加一些趣味。只需 5-10 分鐘即可玩轉示例腳本。你可能發現一個幾乎滿足你需求的經典實例;如果找不到,也很容易自己編寫一個。即使你真的玩不轉,也只是浪費了 5-10 分鐘而已。

資源

安裝方式

支持 Tkinter 的系統就支持 PySimpleGUI,甚至包括樹莓派Raspberry Pi,但你需要使用 Python 3。

pip install PySimpleGUI

文檔

via: https://opensource.com/article/18/8/pysimplegui

作者:Mike Barnett[5] 選題:lujun9972 譯者:pinewall 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出

相關焦點

  • 七個Python必備的GUI庫,這次一定要學會!
    使用wxPython創建的應用程式(GUI)在所有平臺上都具有原生外觀。pip install -i https://pypi.tuna.tsinghua.edu.cn/simple wxPython下面使用wxPython創建一個基本的GUI示例。
  • 七個Python必備GUI庫
    基於Qt框架構建,是一個跨平臺框架,可以給各種平臺創建應用程式,包括:Unix、Windows、Mac OS。PyQt將Qt和Python結合在一起。它不只是一個GUI工具包。還包括了線程,Unicode,正則表達式,SQL資料庫,SVG,OpenGL,XML和功能完善的Web瀏覽器,以及許多豐富的GUI小部件集合。使用pip安裝一下。
  • 七個 Python 必備的 GUI 庫,這次一定要學會!
    基於Qt框架構建,是一個跨平臺框架,可以給各種平臺創建應用程式,包括:Unix、Windows、Mac OS。PyQt將Qt和Python結合在一起。它不只是一個GUI工具包。還包括了線程,Unicode,正則表達式,SQL資料庫,SVG,OpenGL,XML和功能完善的Web瀏覽器,以及許多豐富的GUI小部件集合。使用pip安裝一下。
  • 7 個Python必備的GUI庫,這次一定要學會!
    基於Qt框架構建,是一個跨平臺框架,可以給各種平臺創建應用程式,包括:Unix、Windows、Mac OS。PyQt將Qt和Python結合在一起。它不只是一個GUI工具包。還包括了線程,Unicode,正則表達式,SQL資料庫,SVG,OpenGL,XML和功能完善的Web瀏覽器,以及許多豐富的GUI小部件集合。使用pip安裝一下。
  • 圖形用戶界面EasyGUI(Python)
    GUI包括展示數據用的小控制項、輸入的方法、菜單、按鈕和窗口等,用戶通過滑鼠、鍵盤等輸入設備操縱屏幕上的圖標或菜單選項,來執行選擇命令、調用文件、啟動程序等。EasyGUI是一個Python模塊,利用這個模塊可以很容易地建立簡單的GUI。
  • Python GUI開發,效率提升10倍的方法!
    PySimpleGUI 主要特點包括:創建的界面窗口和使用的控制項同之前的 tkinter, Qt, WxPython 和 Remi 一致.所寫代碼相比之前減少50%到90%無需寫回調函數可以訪問所有的GUI框架下的控制項同時支持桌面和web的GUI接口友好不管是新手,還是有經驗的Python開發者,都會被它吸引170多個Demo程序,教你如何集成目前流行的包,比如OpenCV, Matplotlib, PyGame 等說明文檔足夠豐富
  • 推薦一個 Go GUI 實戰項目
    之前寫過一篇文章:Go 真的也可以進行 GUI 開發:還有這樣的圖書呢。今天推薦一個開源 Go GUI 項目:wormhole-gui,項目地址:https://github.com/Jacalz/wormhole-gui。這是一個跨平臺應用程式,可在設備之間輕鬆加密共享文件、文件夾和文本。
  • 13個Python GUI庫
    在構建GUI程序時,通常使用層疊方式。眾多圖形控制元素直接疊加起來。Python GUI庫當使用python編寫應用程式時,你就必須使用GUI庫來完成。對於Python GUI庫,你可以有很多的選擇。目前,Python GUI程序庫有30多個跨平臺框架。現在就列出其中十幾個並簡要描述:1. TkinterTkinter是一個使用Python語言構建的GUI工具包。
  • Python GUI界面編程-初識篇
    它允許Python程式設計師輕鬆,輕鬆地創建具有健壯,功能強大的圖形用戶界面的程序。它是作為一組Python擴展模塊實現的,這些模塊包裝了用C ++編寫的流行wxWidgets跨平臺庫的GUI組件 。例如,要獲取適用於Ubuntu 16.04(和16.10,LinuxMint 18以及其他版本)的GTK3 wxPython構建,可以使用如下pip命令:pip install -U \-f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-16.04 \wxPython
  • 嘗鮮貼:Win10 安裝子系統 GUI 界面
    本文檔以Win10安裝Ubuntu系統為例子展開講解。下載地址 https://sourceforge.net/projects/vcxsrv/安裝以後會有兩個程序,分別是XLaunch和VcXsrv,它們可以用來遠程訪問Linux。
  • 紅隊和藍隊資料集錦
    py,圖形化應用程式聯動 Nmap、Nikto、Hydra 等工具https://github.com/Manisso/fsociety linux 下類似於 kali 的工具包一鍵安裝工具https://github.com/LionSec/katoolin 使用 linux 伺服器自動安裝 kali 工具包https://github.com/skavngr/rapidscan py2,simple
  • Pyautogui庫學習筆記(3)-屏幕截屏、定位功能
    例如,假設計算器應用程式正在您的計算機上運行,如下所示:如果您不知道計算器按鈕所在的確切屏幕坐標,則不能調用moveTo()和click()函數。每次啟動時,計算器可能會出現在稍有不同的位置,從而使您每次都重新找到坐標。
  • 不習慣在終端使用 youtube-dl?可以使用這些 GUI 應用 | Linux 中國
    它是一個非常有用的命令行工具,可以讓你 從 YouTube 和其他一些網站下載視頻。使用 youtube-dl 並不複雜,但我明白使用命令來完成這種任務並不是每個人都喜歡的方式。好在有一些應用為 youtube-dl 工具提供了 GUI 前端。
  • metasploit framework的一些使用姿勢
    , encoders, nops, all-n, --nopsled <length> 為payload預先指定一個NOP滑動長度-f, --format <format> 指定輸出格式 (使用 --help-formats 來獲取msf支持的輸出格式列表)-e, --encoder [encoder] 指定需要使用的
  • MATLAB-06 圖形界面-GUI 程式設計
    左邊文件列表中,出現了兩個關於保存的ggui1的文件當你想要輸入文本時,使用編輯文本。靜態文本/Static Text靜態文本控制項顯示文本行彈出式菜單/Pop-Up Menu當用戶單擊箭頭時,彈出菜單將顯示選擇列表。
  • 【圖像去霧】直方圖均衡化+Retinex理論圖像去霧含GUI matlab源碼
    通過對圖像的特定加工,將被處理的圖像轉化為對具體應用來說視覺質量和效果更「好」或更「有用」的圖像。圖像增強是最基本最常用的圖像處理技術,常用於其他圖像處理的預處理階段。該方法的基本思想是把原始圖像的灰度統計直方圖變換為均勻分布的形式,這樣就增加了像素灰度值的動態範圍,從而達到增強圖像整體對比度的效果。數字圖像是離散化的數值矩陣,其直方圖可以被視為一個離散函數,它表示數字圖像中每一灰度級與其出現概率間的統計關係。
  • python腳本pdb調試工具使用
    pdb是linux的python調試工具,它功能比較齊全,使用起來也很方便, 按一般運維工程師的技術發展來說,最早接觸程式語言應該是shell,