PySimpleGUI - 視窗類



彈出視窗具有預定義的按鈕、文字標籤和文字輸入欄位配置。視窗類允許您設計更靈活的 GUI。除了這些元素之外,還提供了其他元素,例如列表框、複選框、單選按鈕等。您還可以為 GUI 提供菜單系統。某些專門的小部件(例如微調器、滑塊等)也可以用來使設計更有效。

視窗可以是非永續性視窗,類似於彈出視窗。它會阻塞程式流程,直到使用者透過單擊客戶端區域上的按鈕或標題欄中的關閉 (X) 按鈕關閉它。

另一方面,永續性視窗會一直可見,直到發生導致其關閉的事件。非同步視窗是指其內容會定期更新的視窗。

佈局結構

視窗客戶端區域中元素或小部件的放置由列表列表物件控制。每個列表元素對應視窗表面上的一行,並且可能包含 PySimpleGUI 庫中提供的的一個或多個 GUI 元素。

第一步是透過繪製以下圖形來視覺化元素的放置位置:

Layout

視窗上的元素放置在四行中。前三行有一個文字元素(顯示靜態文字)和一個輸入文字元素(使用者可以在其中輸入)。最後一行有兩個按鈕,確定和取消。

這在列表列表中表示如下:

import PySimpleGUI as psg
layout = [
   [psg.Text('Name '),psg.Input()],
   [psg.Text('Address '), psg.Input()],
   [psg.Text('Email ID '), psg.Input()],
   [psg.OK(), psg.Cancel()]
]

此列表物件用作視窗類建構函式的 layout 引數的值。

window = psg.Window('Form', layout)

這將顯示所需的視窗。使用者輸入儲存在名為 values 的字典中。當用戶按下確定按鈕時,會呼叫視窗類的 read() 方法,視窗立即關閉。

呈現視窗的完整程式碼如下:

import PySimpleGUI as psg
psg.set_options(font=('Arial Bold', 16))
layout = [
   [psg.Text('Name ', size=(15,1)),psg.Input(expand_x=True)],
   [psg.Text('Address ', size=(15,1)), psg.Input(expand_x=True)],
   [psg.Text('Email ID ', size=(15,1)), psg.Input(expand_x=True)],
   [psg.OK(), psg.Cancel()]
]
window = psg.Window('Form', layout, size=(715,207))
event, values = window.read()
print (event, values)
window.close()

以下是顯示的 輸出

Layout Structure

按所示輸入資料,然後按“確定”按鈕。值將列印如下:

OK {0: 'Kiran Gupta', 1: 'Mumbai', 2: 'kiran@gmail.com'}

如果在填充資料後,您按下“取消”按鈕,則列印的結果將為:

Cancel {0: 'Kiran Gupta', 1: 'Mumbai', 2: 'kiran@gmail.com'}

永續性視窗

請注意,此視窗在任何按鈕(或標題欄中的“X”按鈕)被點選後立即關閉。為了使視窗保持活動狀態,直到按下稱為退出的一種特殊型別的按鈕或透過按下“X”關閉視窗,read() 方法被放置在一個無限迴圈中,並在發生 WIN_CLOSED 事件(當按下退出按鈕時)或退出事件(當按下“X”按鈕時)時提供斷開功能。

讓我們將上述程式碼中的取消按鈕更改為退出按鈕。

import PySimpleGUI as psg
layout = [
   [psg.Text('Name '), psg.Input()],
   [psg.Text('Address '), psg.Input()],
   [psg.Text('Email ID '), psg.Input()],
   [psg.OK(), psg.Exit()]
]
window = psg.Window('Form', layout)
while True:
   event, values = window.read()
   if event == psg.WIN_CLOSED or event == 'Exit':
      break
   print (event, values)
window.close()

視窗的外觀將與以前類似,只是取消按鈕被替換為退出按鈕。

Persistent Window

輸入的資料將以元組的形式列印。第一個元素是事件,即按鈕的標題,第二個是字典,其鍵是遞增的數字,值是輸入的文字。

OK {0: 'kiran', 1: 'Mumbai', 2: 'kiran@gmail.com'}
OK {0: 'kirti', 1: 'Hyderabad', 2: 'kirti@gmail.com'}
OK {0: 'karim', 1: 'Chennai', 2: 'karim@gmail.com'}

視窗方法

視窗類中定義的重要方法是 read() 方法,用於收集所有輸入元素中輸入的值。視窗類還有其他方法可以自定義外觀和行為。它們列在下面:

序號 方法和描述
1 AddRow

將一行元素新增到視窗的“self.Rows”變數中

2 AddRows

迴圈遍歷元素的列表列表,並將每一行(列表)新增到佈局中。

3 close

關閉視窗,以便正確釋放資源。

4 disable

停用視窗,使其無法接收使用者的任何輸入

5 disappear

使視窗從螢幕上“消失”,但保留在工作列上。

6 enable

重新啟用視窗以接收使用者輸入

7 fill

使用作為字典提供的資料填充作為輸入欄位的元素。

8 find_element

查詢與提供的鍵關聯的元素物件。它等效於“element = window[key]”

9 get_screen_dimensions

獲取螢幕尺寸。

10 hide

隱藏螢幕和工作列中的視窗

11 load_from_disk

從“SaveToDisk”函式建立的 Pickle 檔案中恢復值

12 layout

使用小部件列表列表填充視窗。

13 read

從視窗獲取所有資料。傳入超時時間(以毫秒為單位)以等待。

14 reappear

使消失的視窗再次顯示。

15 save_to_disk

將每個輸入元素中包含的值儲存到 pickle 檔案中。

16 set_title

更改工作列中視窗的標題

使用鍵更新視窗

使用者在窗口布局上的不同輸入元素中輸入的資料以字典格式儲存。字典鍵從 0 開始編號,對應於從左到右、從上到下的輸入元素。我們可以透過字典運算子引用輸入資料。這意味著,第一個元素中的資料由“values[0]”返回。

values = {0: 'kiran', 1: 'Mumbai', 2: 'kiran@gmail.com'}
data = [values[k] for k in values.keys()]
print (data)

它將在控制檯上列印以下內容:

['kiran', 'Mumbai', 'kiran@gmail.com']

但是,如果您想以程式設計方式操作元素的值,則必須透過為其 key 引數分配唯一字串值來初始化該元素。元素的鍵類似於變數或識別符號的名稱,這使得以程式設計方式處理讀取或為其賦值變得方便。

key 引數應為字串。約定是它應該是一個以“-”字元開頭和結尾的大寫字串(例如:“- NAME-”)。但是,可以使用任何字串。

讓我們在上面的示例中為輸入元素分配鍵,如下所示:

layout = [
   [psg.Text('Name '),psg.Input(key='-NM-')],
   [psg.Text('Address '), psg.Input(key='-AD-')],
   [psg.Text('Email ID '), psg.Input(key='-ID-')],
   [psg.OK(), psg.Exit()],
]

結果,read() 方法返回的 values 字典將包含鍵識別符號,而不是以前的整數。

OK {'-NM-': 'Kiran', '-AD-': 'Mumbai', '-ID-': 'kiran@gmail.com'}

現在,values['-NM-'] 將獲取“Kiran”。鍵可以分配給任何元素,而不僅僅是輸入元素。您可以使用相同的鍵來呼叫元素上的 Update。我們可以使用視窗物件的“find_element(key)”或使用 window['key'] 來引用該元素。

讓我們擴充套件我們之前的示例,在確定和取消按鈕之前新增一行,並新增一個帶有“-OUT-”鍵的空文字元素。在 OK 事件中,此文字標籤顯示在具有鍵“-NM-”、“-AD-”和“-ID-”的三個輸入元素中輸入的資料的串聯。

import PySimpleGUI as psg
psg.set_options(font=('Arial Bold', 16))
layout = [
   [psg.Text('Name ', size=(15, 1)),
   psg.Input(key='-NM-', expand_x=True)],
   [psg.Text('Address ', size=(15, 1)),
   psg.Input(key='-AD-', expand_x=True)],
   [psg.Text('Email ID ', size=(15, 1)),
   psg.Input(key='-ID-', expand_x=True)],
   [psg.Text('You Entered '), psg.Text(key='-OUT-')],
   [psg.OK(), psg.Exit()],
]
window = psg.Window('Form', layout, size=(715, 200))
while True:
   event, values = window.read()
   print(event, values)
   out = values['-NM-'] + ' ' + values['-AD-'] + ' ' + values['-ID-']
   window['-OUT-'].update(out)
   if event == psg.WIN_CLOSED or event == 'Exit':
      break
window.close()

執行上述程式碼,在三個輸入元素中輸入文字,然後按 OK。-OUT- 文字標籤將更新如下所示:

Update Window

另一個使用 key 屬性的示例如下。為輸入元素分配鍵引數 -FIRST- 和 -SECOND-。有兩個按鈕,標題分別為 Add 和 Sub。文字元素顯示兩個數字的加法或減法,具體取決於按下的按鈕。

import PySimpleGUI as psg
import PySimpleGUI as psg
psg.set_options(font=('Arial Bold', 16))
layout = [
   [psg.Text('Enter a num: '), psg.Input(key='-FIRST-')],
   [psg.Text('Enter a num: '), psg.Input(key='-SECOND-')],
   [psg.Text('Result : '), psg.Text(key='-OUT-')],
   [psg.Button("Add"), psg.Button("Sub"), psg.Exit()],
]
window = psg.Window('Calculator', layout, size=(715, 180))
while True:
   event, values = window.read()
   print(event, values)
   if event == "Add":
      result = int(values['-FIRST-']) + int(values['-SECOND-'])
   if event == "Sub":
      result = int(values['-FIRST-']) - int(values['-SECOND-'])
   window['-OUT-'].update(result)
   if event == psg.WIN_CLOSED or event == 'Exit':
      break
window.close()

以下螢幕截圖顯示按下“Add”按鈕時的結果。

Updated Window

無邊框視窗

預設情況下,應用程式視窗是在客戶端區域上方建立了一個標題欄,其中所有其他元素都放置在佈局中。標題欄左側包含視窗標題,右側包含控制按鈕(最小化、恢復/最大化和關閉)。但是,特別是對於類似售貨亭的應用程式,不需要標題欄。您可以透過將視窗物件的“no_titlebar”屬性設定為“True”來去除標題欄。

Border Window

要終止此類應用程式,必須在發生退出按鈕事件時終止事件迴圈。

停用關閉的視窗

如果您希望阻止使用者最小化應用程式視窗,則應將視窗物件的“disable_minimize”屬性設定為 True。類似地,將“disable_close”屬性設定為 True,關閉按鈕將顯示,但不會建立 WINDOW_CLOSED 事件。

Border Disabled

透明視窗

視窗物件的“alpha_channel”屬性決定視窗的透明度。其值介於 0 到 1 之間。預設情況下,它為 0,這意味著視窗顯示為不透明。將其設定為 1 以使其完全透明。0 到 1 之間的任何浮點值都會使透明度成比例。

Transparent Window

多個視窗

PySimpleGUI 允許同時顯示多個視窗。當 PySimpleGUI 模組中的靜態函式被呼叫時,它會讀取所有活動視窗。要使視窗處於活動狀態,必須將其完成。該函式返回一個 (window, event, values) 結構的元組。

window, event, values = PySimpleGUI.read_all_windows()

如果沒有視窗開啟,則其返回值為 (None, WIN_CLOSED, None)

在以下程式碼中,兩個函式“win1()”和“win2()”在被呼叫時分別建立一個視窗。從第一個視窗開始,標題為 Window-2 的按鈕會開啟另一個視窗,以便兩個視窗都處於活動狀態。當第一個視窗上發生 CLOSED 事件時,這兩個視窗都關閉,程式結束。如果按下第二個視窗上的“X”按鈕,則將其標記為已關閉,保留第一個視窗開啟。

import PySimpleGUI as psg
def win1():
   layout = [
      [psg.Text('This is the FIRST WINDOW'), psg.Text('', key='-OUTPUT-')],
      [psg.Text('popup one')],
      [psg.Button('Window-2'), psg.Button('Popup'), psg.Button('Exit')]
   ]
   return psg.Window('Window Title', layout, finalize=True)
   def win2():
      layout = [
         [psg.Text('The second window')],
         [psg.Input(key='-IN-', enable_events=True)],
         [psg.Text(size=(25, 1), key='-OUTPUT-')],
         [psg.Button('Erase'), psg.popup('Popup two'), psg.Button('Exit')]]
         return psg.Window('Second Window', layout, finalize=True)
window1 = win1()
window2 = None
while True:
   window, event, values = psg.read_all_windows()
   print(window.Title, event, values)
   if event == psg.WIN_CLOSED or event == 'Exit':
      window.close()
   if window == window2:
      window2 = None
   elif window == window1:
      break
   elif event == 'Popup':
      psg.popup('Hello Popup')
   elif event == 'Window-2' and not window2:
      window2 = win2()
   elif event == '-IN-':
      window['-OUTPUT-'].update('You entered {}'.format(values["-IN-"]))
   elif event == 'Erase':
      window['-OUTPUT-'].update('')
      window['-IN-'].update('')
window.close()

它將生成以下 輸出 視窗

Multiple Windows

非同步視窗

視窗類的 read() 方法具有以下附加引數:

window.read(timeout = t, timeout_key=TIMEOUT_KEY, close=False)

timeout 引數允許您的 GUI 在非阻塞讀取情況下使用。它是您的裝置在返回之前可以等待的毫秒數。它建立了一個定期執行的視窗。

您能夠新增到超時值的時間越長,您佔用的 CPU 時間就越少。在超時時間內,您正在“讓出”處理器以執行其他任務。您的 GUI 將比使用非阻塞讀取時更具響應性。

timeout_key 引數有助於確定在規定時間內是否有任何使用者操作。timeout_key 的預設值為“__timeout__”。

while True:
   event, value = window.read(timeout=10)
   if event == sg.WIN_CLOSED:
      break
   if event == sg.TIMEOUT_KEY:
      print("Nothing happened")

要使視窗可移動,請將視窗物件的“grab_anywhere”屬性設定為 true。如果“keep_on_top”屬性設定為 True,則視窗將保持在當前視窗之上。

廣告