PySimpleGUI筆記

TheHypocrite發表於2024-07-10

PySimpleGUI --Python圖形化介面庫

4.60.5版本及之前都是免費的,現在5.0.0版本之後開始收費了。

太貴了跑路了

安裝:

pip install PySimpleGUI

1 佈局模板

1.1 常用佈局

import PySimpleGUI as sg

layout = [
    [],
    [],
    [],
    [],
    [],
]
#每個[]是一行
window = sg.Window('',layout)

while True:
    event,values = window.read()
    if event == None:
        break
window.close()

image

1.2 加號佈局

import PySimpleGUI as sg

layout = [
    [sg.Text('請輸入基本資訊')],
    [[sg.Text('姓名')]+[sg.In()]]+[
     [sg.Text('性別')]+[sg.In()]]+[
     [sg.Text('國籍')]+[sg.In()]]+[
    [sg.B('確認')]+[sg.B('取消')]]
]
window = sg.Window('Python佈局2',layout)
while True:
    event, values =window.read()
    if event == sg.WIN_CLOSED:
        break
    if event == '確認':
        break
window.close()

1.3 迴圈佈局

import PySimpleGUI as sg

layout = [
    [[sg.In(i)] for i in ['姓名','性別','國籍']]
]

window = sg.Window('Python',layout)

while True:
    event, values =window.read()
    if event == sg.WIN_CLOSED:
        break

window.close()

2 選單

2.1 選單欄

  	menu_def = [['&File', ['&New', '&Open', '!Save', 'E&xit', ]],
                ['&Edit', ['C&ut', '&Copy::CP', '&Paste', '&Undo'], ],
                ['&Help', '&About...'], ]

image

2.2 右鍵選單

rightclick=['&Edit', ['C&ut', '&Copy','&Paste', '&Undo']]
menu_def = [
   ['&File', ['&New', '&Open', '&Save', 'E&xit',]], rightclick,
   ['&Help', '&About...'],
]
#將其用作 Window 建構函式中 right_click_menu 引數的值
window=psg.Window("Menu", layout, size=(715, 300), right_click_menu=rightclick)

3 彈出視窗

3.1 基本彈窗

  • popup_ok − 僅顯示帶有 OK 按鈕的 Popup
  • popup_ok_cancel − 顯示帶有 OK 和 Cancel 按鈕的彈出視窗
  • popup_cancel − 顯示帶有"cancelled"已取消按鈕文字的彈出視窗
  • popup_yes_no − 顯示帶有 Yes 和 No 按鈕的彈出視窗
  • popup_error − 帶有彩色按鈕和"Error"錯誤作為按鈕文字的彈出視窗

這些函式返回使用者按下的按鈕的文字。 例如,如果使用者按下 ok-cancel 彈出視窗的 OK 按鈕,它會返回 Ok,這可以在進一步的程式設計邏輯中使用。

以下彈出視窗接受使用者以文字形式輸入或讓使用者從選擇器中選擇檔案/資料夾/日期。

  • popup_get_text − 顯示帶有文字輸入欄位的彈出視窗。 返回輸入的文字,如果關閉/取消則返回 None

  • popup_get_file − 顯示帶有文字輸入欄位和瀏覽按鈕的彈出視窗,以便使用者可以選擇檔案。

  • popup_get_folder − 顯示帶有文字輸入欄位和瀏覽按鈕的彈出視窗,以便可以選擇資料夾。

  • popup_get_date − 顯示一個日曆視窗,獲取使用者的選擇,以元組形式返回(mon, day, year)

  • popup_scrolled − 滾動彈窗

    import PySimpleGUI as sg
    pwd = '123'
    list = ['資料1','資料2','資料3','資料4']
    while True:
        result = sg.PopupGetText('密碼輸入框')
        if pwd ==result :
            break
        elif result ==None:
            exit()
        else:sg.popup('密碼錯誤')
    layoutb=[[sg.LB(list,size=(30,5))]]
    layout=[[sg.Frame('資料庫',layoutb)]]
    
    window=sg.Window('演示',layout)
    while True:
        event, values = window.read()
        if event == None:
            break
    
    window.close()
    """
    sg.PopupGetFile()#檔案選擇彈窗
    sg.PopupGetFolder()#資料夾選擇
    sg.PopupAnnoying()#沒有標題欄可隨意移動
    sg.PopupAutoClose()#顯示一段時間自動關閉
    sg.PopupCancel()
    sg.PopupOKCancel()
    sg.PopupOK()
    sg.PopupError()
    sg.PopupNoButtons()
    """
    

    執行截圖:

image

點選OK

image

4 元素類

Text 文字元素 在視窗中顯示一些文字。 通常這意味著單行文字。
Input 輸入元素 顯示單個文字輸入欄位。
Multiline 多行元素 顯示和/或閱讀多行文字。 這既是輸入元素也是輸出元素。
Combo 組合元素 單行輸入和下拉選單的組合。
OptionMenu 元素 類似於 Combo。 僅在 TKinter 埠上
Checkbox 核取方塊元素 顯示覆選框和旁邊的文字。 CB
Radio 單選元素 在一組其他單選元素中使用,使使用者能夠在選項列表中僅選擇一個選項。 R
Spin 元素 帶有向上/向下按鈕和單行文字的旋轉器。
Button 按鈕元素 定義所有可能的按鈕。 諸如 Submit、FileBrowse 之類的快捷方式……每個都建立一個 Button
ButtonMenu 按鈕選單元素 建立一個按鈕,單擊該按鈕將顯示類似於右鍵單擊選單的選單。
Slider 滑塊元素 用於遞增/遞減值的水平或垂直滑塊。
Listbox 列表框元素 提供一個值列表供使用者選擇一個或多個。 執行 window.read() 時返回選定行的列表。
Image 影像元素 在視窗中顯示影像。 應僅為 GIF 或 PNG。
Graph 圖形元素 建立繪製圖形的區域
Canvas 畫布元素 繪製形狀的區域
ProgressBar 進度條元素 顯示一個彩色條,該條在某些操作的進度中帶有陰影。
Table 表格元素 在行和列中顯示資料
Tree 樹元素 以樹狀方式呈現資料,很像檔案/資料夾瀏覽器。
Sizer 元素 此元素用於新增更多空間。
StatusBar 元素 StatusBar 元素在底部建立凹陷的文字填充條。
Frame 框架元素 Frame 元素是一個容器物件,它包含一個或多個其他型別的元素。
Column 列元素 如果你想設計一個或多個垂直列表示的 GUI 視窗元素,這將非常有用。
Tab 元素 Tab 元素的使用使設計非常方便、有效且易於使用者導航。 Tab 元素也是一個容器元素,例如 Frame 或 Column。

4.1 元素類方法

set_tooltip() 由應用程式呼叫以更改元素的工具提示文字
set_focus() 將當前焦點設定在此元素上
set_size() 將元素的大小更改為特定大小
get_size() 以畫素為單位返回元素的大小
expand() 使元素擴充套件以填充 X 和 Y 方向的可用空間
set_cursor() 為當前元素設定游標
set_right_click_menu() 設定單擊時呼叫的右鍵單擊選單

5 主題

import PySimpleGUI as sg

print(sg.theme_list())
sg.theme('DarkRed')
sg.Popup('彈窗演示')
# print(sg.theme_button_color())
sg.theme_button_color(('black', '#ad1d45'))
sg.Popup('演示彈窗','按鍵字型變黑色')

6 將程式打包成exe

安裝pysimplegui-exemaker:

pip install pysimplegui-exemaker

執行:

python -m pysimplegui-exemaker.pysimplegui-exemaker

7 各種例子

以下是在下學習PySimpleGUI過程中的用到的例項

7.1 下拉選單

import PySimpleGUI as sg
list=['Python','JavaScript','C/C++','PHP','Java','C#','go','vue','VB']

layout=[[sg.Drop(list,
               default_value='Python',
               key='-LIST-',
               size=(30,6),
               enable_events=None,
               bind_return_key=None,
               font=('楷體',20),
               background_color='yellow',
               text_color='red',
               pad=20,
               tooltip='列表',
               visible=True,
               auto_size_text=True
               )]]
window=sg.Window('列表',layout)
while True:
    event, values =window.read()
    if event == None:
        break
    if event == '-LIST-':
        print(values)

window.close()

7.2 下拉選單更新

import PySimpleGUI as sg
#透過值獲取鍵
def get_keys_by_value(dictionary, value):
    keys = []
    for key, val in dictionary.items():
        if val == value:
            keys.append(key)
    return "".join(keys)
dict ={'河南':'鄭州','河北':'石家莊','浙江':'杭州','湖北':'武漢'}
list1 = []
list2 = []
for i in dict:
    list1.append(i)
for i in dict:
    list2.append(dict[i])
layout = [[sg.Combo(list1,key='-DICT1-',size=(40,6),enable_events=True)],
          [sg.T('行政中心'),sg.Input(key='-INPUT-',size=(30))],
          [sg.Combo(list2,key='-DICT2-',size=(40,6),enable_events=True)]]
window = sg.Window('演示',layout)

while True:
    event, values =window.read()
    if event == None:
        break
    if event == '-DICT1-':
        window['-DICT2-'].update(dict[values['-DICT1-']])
        window['-INPUT-'].update(dict[values['-DICT1-']])
    if event == '-DICT2-':
        window['-DICT1-'].update(get_keys_by_value(dict,values['-DICT2-']))
window.close()

7.3 中英切換

import PySimpleGUI as sg

layout = [[sg.B('中文'),sg.B('English')],
          [sg.T('請輸入基本資訊',key='-Text1-')],
          [sg.Text('姓名',key='-Name-',size=(8,1)),sg.InputText()],
            [sg.Text('性別',key='-Sex-',size=(8,1)),sg.InputText()],
            [sg.Text('國籍',key='-Nationality-',size=(8,1)),sg.InputText()],
            [sg.Button('確認',key='-Confirm-',size=(8,1)),sg.Button('取消',key='-Cancel-')]
          ]
window = sg.Window('Python GUI',layout)

while True:
    event, values =window.read()
    if event ==None:
        break
    if event =='English':
        window['-Text1-'].update(value='Please enter basic information')
        window['-Name-'].update(value='Name')
        window['-Sex-'].update(value='Sex')
        window['-Nationality-'].update(value='Nationality')
        window['-Confirm-'].update(text='Confirm')
        window['-Cancel-'].update(text='Cancel')
    if event =='中文':
        window['-Text1-'].update(value='請輸入基本資訊')
        window['-Name-'].update(value='姓名')
        window['-Sex-'].update(value='性別')
        window['-Nationality-'].update(value='國籍')
        window['-Confirm-'].update(text='確認')
        window['-Cancel-'].update(text='取消')

window.close()

7.4 列元素

import PySimpleGUI as sg

layoutL = [[sg.T('標題')],
           [sg.In('請輸入文章標題')],
           [sg.T('作者')],
           [sg.In('請輸入姓名或筆名')]]
layoutR = [[sg.ML('請輸入正文內容',size=(30,20))],
           [sg.B('確認提交')],
           ]
layout = [[sg.Col(layoutL,
                  background_color='black',
                  size=(200,100),
                  scrollable=True,
                  vertical_scroll_only=None,
                  right_click_menu=None,
                  visible=True,
                  justification='left',
                  element_justification='Center',
                  vertical_alignment='top',
                  grab=True,#True可以拖動
                  expand_x=True,
                  expand_y=True
                  ),
           sg.Col(layoutR)]]
window = sg.Window('列元素',layout)
while True:
    event, values = window.read()
    if event == None:
        break

window.close()

7.5 列表

import colorsys

import PySimpleGUI as sg
list=['Python','JavaScript','C/C++','PHP','Java','C#','go','vue','VB']

layout=[[sg.LB(list,
               # default_values=['Python'],
               key='-LIST-',
               select_mode='extended',
               size=(30,6),
               enable_events=None,
               bind_return_key=None,
               font=('楷體',20),
               background_color='yellow',
               text_color='red',
               pad=20,
               tooltip='列表',
               right_click_menu=['&選單',['貼上','剪下','複製']],
               visible=True,
               auto_size_text=True
               )]]
window=sg.Window('列表',layout,size=(800,600))
while True:
    event, values =window.read()
    if event == None:
        break
    if event == '-LIST-':
        print(values)

window.close()

7.6 列表更新方法

import PySimpleGUI as sg

list1=['甲','乙','丙','丁','戊']
list2=['子','醜','寅','卯','辰']

layout=[[sg.LB(list1,key='-list-',size=(30,2))],
        [sg.B('天干'),sg.B('地支')],
        [sg.B('set_to_index'),sg.B('scroll_to_index')]]

window=sg.Window('演示視窗',layout)

while True:
    event, values =window.read()
    print(event)
    if event == None:
        break
    if event == '天干':
        window['-list-'].update(values=list1)
    if event == '地支':
        window['-list-'].update(values=list2)
    if event == 'set_to_index':
        window['-list-'].update(set_to_index=0)
        print(window['-list-'].get())
    if event == 'scroll_to_index':
        window['-list-'].update(scroll_to_index=3)
        print(window['-list-'].get())

window.close()

7.7 單_多選框屬性設定更新

import PySimpleGUI as sg
import get_keys_by_value
list=['非常滿意','滿意','一般','不滿意']

layout=[[sg.Text('請對這位男士做出評價(單選框)')],
        [sg.R(i,group_id=1,key=i)for i in list],
        [sg.Text('請對這位男士做出評價(多選框)')],
        [sg.CB(i,key=i)for i in list],
        [sg.B('確認提交')]
        ]

window=sg.Window('演示介面',layout)

while True:
    event, values = window.read()
    if event == None:
        break
    if event == '確認提交':
        for k,v in values.items():
            if v == True:
                print(k)
window.close()

7.8 單行輸入框登入介面

import PySimpleGUI as sg
import 選單
User1={'使用者名稱':'lisi','密碼':'123'}
User2={'使用者名稱':'zhangsan','密碼':'345'}
UserList=[User1,User2]
layout = [[sg.Text('賬號:'),
           sg.Input(
             '請輸入您的賬號',
            key='-Account-',
            size=(30,None),#寬、高
            disabled=False,#元素禁用,True時無法輸入任何值
            password_char=None, #密碼字元
            justification='l',#對齊方式
            background_color='white',#輸入框顏色
            text_color='green',
            font=('楷體',12),
            tooltip=None,#懸浮文字
            border_width=5,#邊框界線寬度
            enable_events=True,#True輸入值會發生一個事件
            do_not_clear=True,#True輸入框內容不會被清除,False時發生事件輸入會清除
            focus=True,#設定焦點,若為True,則游標顯示在此輸入框
            pad=None,
            disabled_readonly_background_color='black',#禁用時背景顏色
            disabled_readonly_text_color='red',#禁用時文字顏色
            right_click_menu=None,
            visible=True

            )],
          [sg.T('密碼:'),sg.InputText(
            key='-Password-',
            size=(30,None),
            disabled=None,
            tooltip='3位密碼',
            password_char='*',
            justification='l',
            background_color='white',
            text_color='green',
            font=('楷體',12),
            border_width=5,#邊框界線寬度
            focus=False,
          )],
          [sg.B('確定'),sg.B('取消')],
          [sg.T('',key='-Text-',size=(30,None))]]

window = sg.Window('Python GUI',layout)
while True:
    event, values = window.read()
    if event == None:
        break
    if event == '-Account-':
        print('-Account-')
    if event == '確定':
        for user in UserList:
            if values['-Account-']==user['使用者名稱'] and values['-Password-']==user['密碼']:
                msg='輸入正確'
                sg.popup(msg)
                window.close()
                選單.Gui()
            else:
                msg='輸入有誤'
                sg.popup(msg)
            break

window.close()

7.9 單選框

import PySimpleGUI as sg

lista=['非常滿意','滿意','一般','不滿意']
listb=['請對這位先生做出評價:','請對這位女士做出評價:']

# layout=[
#     [sg.T('1.'+listb[0])],
#     [sg.R(i,group_id=1)for i in lista],
#     [sg.T('2.'+listb[1])],
#     [sg.R(i,group_id=2)for i in lista]
# ]

# layout=(
#         [[sg.T('1.'+listb[0])]]
#         +
#         [[sg.R(i,group_id=1,key='-R1-')]for i in lista]#縱向的單選框[ [sg.R()]  for i in list]
#         +
#         [[sg.T('2.'+listb[1])]]
#         +
#         [[sg.R(i,group_id=2,key='-R2-')for i in lista]]
#         +
#         [[sg.B('確認',enable_events=True)]]
#         +
#         [[sg.T('',key='-Text-')]]
# )
layout=[[sg.T(str(y+1))]+[sg.R(x,group_id=y,key=(x,y)) for x in lista] for y in range(9)]
window=sg.Window('演示',layout)
while True:
    event, values =window.read()
    if event == None:
        break
    if event == '確認':
        if values['-R1-'] and values['-R2-'] != None:
            window['-Text-'].update('感謝您的評價')
        else: window['-Text-'].update('請填寫完整')

window.close()

7.10 圖片元素

import PySimpleGUI as sg

img =r'D:\ph\ph'
base64_gif=sg.DEFAULT_BASE64_LOADING_GIF
layout = [[[sg.Image(filename=img+f'{i}.png')]for i in range(1,4)],
          [sg.Image(data=base64_gif,key='-GIF-')]]

window = sg.Window('演示',layout)
while True:
    event, values =window.read(timeout=10)
    window['-GIF-'].update_animation(source=base64_gif,time_between_frames=110)
    if event ==None:
        break


window.close()

7.11 圖片轉編碼

import base64
f = open(r"C:\\Users\Administrator\Pictures\影片專案\cat.jpg","rb")
res = f.read()
s = base64.b64encode(res)
print(s)
f.close()

7.12 多行文字框

import PySimpleGUI as sg

text = """
春江潮水連海平,海上明月共潮生。
豔豔隨波千萬裡,何處春江無月明。
江流宛轉繞芳甸,月照花林皆似霰。
空裡留霜不覺飛,汀上白沙看不見。
江天一色無纖塵,皎皎空中孤月輪。
江畔何人初見月,江月何年初照人。
人生代代無窮已,江月年年望相似。
"""
layout = [[sg.ML(default_text=text,
             key='-TEXT-',
            disabled=False,
            border_width=None,
            size=(50,6),
            background_color='white',
            text_color='black',
            font=('楷體',20),
            enable_events=True,
            write_only=False,#當True時,只提供寫入,視窗不讀取,無返回值
            reroute_stdout=True,#print語句會顯示在此文字框內
            reroute_cprint=True,#使用cprint將內容列印到此文字框內
            reroute_stderr=False,#捕捉異常時將文字寫在此元素內,sys.stderr.write('?')
            autoscroll=False,#如果為True,更多資料新增到末尾時元素的內容將自動滾動
            focus=False,
            tooltip='作者:張若虛',
            justification='center',
            right_click_menu=['選單',['複製','貼上','剪下','全選']],
            visible=True,
            do_not_clear=True#False視窗讀取一次,內容清除
                 )],
          [sg.In(key='-INPUT1-'),
           #垂直分割線
           sg.VerticalSeparator(color='red',
                                key='-VERTICAL-',
                                pad=((10,10),(10,10))),#間隔((左,右),(上,下))
           sg.B('CPrint',key='-OUTPUT1-')],

          [sg.In(key='-INPUT2-'),
           sg.VerticalSeparator(color='red'),
           sg.B('Print',key='-OUTPUT2-')],

          [sg.B('更新',key='-UPDATE-')]]

window = sg.Window('Window Title', layout)
while True:
    event, values = window.read()
    if event ==None:
        break
    if event == '-OUTPUT1-':
        sg.cprint(values['-INPUT1-'],
                  end=None,
                  sep='',#分割符
                  text_color='black',
                  background_color='Light green',
                  justification='right'
                  )
        window['-INPUT1-'].update('')
    if event == '-OUTPUT2-':
        window['-TEXT-'].print(values['-INPUT2-'],
                               end=None,
                               sep='--',  # 分割符
                               text_color='black',
                               background_color='Light blue',
                               justification='left'
                               )
        window['-INPUT2-'].update('')

    if event == '-UPDATE-':
        window['-TEXT-'].update(value='你好!',
                                disabled=None,
                                append=True,
                                font=None,
                                text_color=None,
                                background_color=None,
                                justification='left',
                                visible=True,
                                autoscroll=True

                                )
window.close()

7.13 彈窗

import PySimpleGUI as sg
a=sg.popup('彈窗\n'*5,
         title='演示',
         button_color=('red', 'green'),
         background_color='black',
         auto_close=True,#自動關閉彈窗
         auto_close_duration=3,#自動關閉彈窗持續時間
        custom_text=('yes','no'),#自定義按鈕文字
        non_blocking=False,#非阻塞設定,如果為True,立即執行下一步,不需要等待使用者的輸入,
         font=('Arial'),
         no_titlebar=False,#不顯示標題欄
         grab_anywhere=True,
         # location=(600,700),
         any_key_closes=True,#True敲打任意鍵就會關閉介面
         image=r'C:\Users\風車小牛馬\Pictures\icons\1.png',
         modal=True
         )

print(a)

7.14 彈窗之PopupGetText

import PySimpleGUI as sg
pwd = '123'
list = ['資料1','資料2','資料3','資料4']
while True:
    result = sg.PopupGetText('密碼輸入框')
    if pwd ==result :
        break
    elif result ==None:
        exit()
    else:sg.popup('密碼錯誤')
layoutb=[[sg.LB(list,size=(30,5))]]
layout=[[sg.Frame('資料庫',layoutb)]]

window=sg.Window('演示',layout)
while True:
    event, values = window.read()
    if event == None:
        break

window.close()
"""
sg.PopupGetFile()#檔案選擇彈窗
sg.PopupGetFolder()#資料夾選擇
sg.PopupAnnoying()#沒有標題欄可隨意移動
sg.PopupAutoClose()#顯示一段時間自動關閉
sg.PopupCancel()
sg.PopupOKCancel()
sg.PopupOK()
sg.PopupError()
sg.PopupNoButtons()
"""

7.15 按鍵元素設定

import PySimpleGUI as sg

image_file =r'..//image/1.png'
layout = [[sg.Text('使用者名稱',size=8,background_color='white',text_color='black'),sg.Input(key='-user-')],
          [sg.Text('密碼',size=8,background_color='white',text_color='black'),sg.Input(key='-pwd-')],
          [sg.Column([[sg.Button(image_filename=image_file,
                     key='-python-',
                     image_size=(32,32),
                     button_color='white',
                     bind_return_key=True,
                     auto_size_button=True)]],justification='center')]
          ]#按鈕居中對齊
window = sg.Window('Python練習',layout,keep_on_top=True,background_color='white')

while True:
    event, values =window.read()
    print(event)
    if event ==None:
        break
    if event =='-python-':
        print(event)

window.close()

7.16 檔案選擇器和另存為

import PySimpleGUI as sg

layout = [[sg.FilesBrowse(button_text="選擇檔案",
                         target='-IN1-',#目標元素
                         file_types=(('ALL Files','*.*'),),#選擇檔案型別
                         initial_folder=r'C:\Users\風車小牛馬\Pictures\icons'),#預設跳轉路徑
           sg.In(key='-IN1-')],
          [sg.FolderBrowse(button_text="選擇資料夾",target='-IN2-'),sg.In(key='-IN2-')],
          [sg.SaveAs(button_text="另存為",target='-IN3-'),sg.In(key='-IN3-')]]

window = sg.Window('檔案選擇器',layout)
while True:
    event, values = window.read()
    if event ==None:
        break


window.close()

7.17 文字元素

import PySimpleGUI as sg

text = '''
《逢雪宿芙蓉山主人》
——唐代·劉長卿
日暮蒼山遠,
天寒白屋貧。
柴門聞犬吠,
風雪夜歸人。
'''
layout = [[sg.T(text,
        key='-text-',#元素唯一識別符號,用於元素定位
        size=(None,None),#元素寬高(int,int)
        font=('楷體',20),#字型
        auto_size_text=True,#當值設為True時,視窗自動適應文字大小
        enable_events=True,#bool:事件屬性,設定為True時,點選文字發生事件
        relief='ridge',#浮雕設計‘raised’,'sunken','flat','ridge','solid','groove'
        border_width=30,#設定relief時,用來設定邊界寬度
        text_color='blue',#文字顏色
        background_color='white',#背景顏色
        justification='center',#對齊方式
        pad=None,#元素間隔
        right_click_menu=['&Edit',['&Copy','&Paste','&Undo','&More',['&Setting','&About']]],#右鍵調出選單
        grab=False,#設為True時點選移動
        tooltip='這是一個標識文字',
        visible=True#顯示視窗
        )]]

window = sg.Window('文字元素',layout)

while True:
    event, values = window.read()
    if event ==None:
        break
    if event == '-text-':
        sg.Popup('執行了一個點選事件')

window.close()

7.18 文字元素更新

import PySimpleGUI as sg

layout = [[sg.Text('Hypocrite',key='-Text-'),sg.Button('點贊')]]

window = sg.Window('Python',layout)

while True:
    event, values =window.read()
    print(event)
    if event == None:
        break
    if event == '點贊':
        window['-Text-'].update(
            value='Hello World!',
            background_color='white',
            text_color='black',
            font=('楷體',20),
            visible=True
        )
window.close()

7.19 標籤

import PySimpleGUI as sg

lista=['蘋果','香蕉','橘子','橙子']
listb=['白菜','芥菜','包菜','生菜']

tab1_layout=[[sg.LB(lista,size=(20,10))]]
tab2_layout=[[sg.LB(listb,size=(20,10))]]
layout=[[sg.TabGroup([[sg.Tab('水果類',tab1_layout,title_color='red'),
                       sg.Tab('蔬菜類',tab2_layout)]],
                     tab_location='lefttop',
                     title_color='black',#未選中
                     tab_background_color='gray',
                     selected_title_color='blue',#選中
                     background_color='gray',#標籤標題所在空白區域的背景顏色
                     selected_background_color='white',#選中
                     font=('楷體',12),
                     enable_events=False,
                     border_width=10
                     )]]
window=sg.Window('標籤演示',layout,keep_on_top=True,background_color='gray')
while True:
    event, values = window.read()
    if event == None:
        break

window.close()

7.20 框架元素

import PySimpleGUI as sg
list = ['資料1','資料2','資料3','資料4']
layouta=[[sg.Text('賬號'),sg.Input()],
         [sg.Text('賬號'),sg.Input()],
         [sg.Col([[sg.B('登入')]],justification='center')]]
layoutb=[[sg.LB(list,size=(30,5))]]
layout=[[sg.Frame('登入項',layouta,
                  title_color='green',
                  background_color=None,
                  title_location='n',#12種[東南西北]
                  relief="groove",
                  key='-a-',
                  visible=True
                  ),sg.Frame('資料庫',layoutb,visible=False,key='-b-')]
        ]
window=sg.Window('框架',layout)
while True:
    event, values = window.read()
    if event == None:
        break
    if event =='登入':
        window['-a-'].update(visible=False)
        window['-b-'].update(visible=True)



window.close()

7.21 滑塊

import PySimpleGUI as sg

flag=0
layout = [[sg.T('酸性',size=(33,None),justification='left',text_color='red'),
           sg.T('中性',size=(69,None),justification='center',text_color='white'),
           sg.T('鹼性',size=(33,None),justification='right',text_color='blue')],
    [sg.Slider(
    range=(0,14),#數值範圍
    key='-SD-',#鍵值
    default_value=7,#起始預設值
    resolution=0.1,#每次移動間隔
    tick_interval=True,#標識
    orientation='horizontal',#方向
    disable_number_display=False,#是否顯示滑塊旁數值
    border_width=5,#
    relief='raised',#樣式
    size=(100,20),#大小
    font=('Arial',12,'bold'),#字型
    background_color='Light blue',#背景顏色
    text_color='red',#文字顏色
    tooltip=None,#懸浮文字
    visible=True#可見狀態
)],
          [sg.Column([[sg.B('上調',size=(10,2)),sg.B('下調',size=(10,2))]], justification='center')],
          [sg.Column([[sg.B('確認'),sg.B('重置')]],justification='center')],
          [sg.T('',key='-TEXT-',justification='center',size=110,font=('楷書'))]

]

window = sg.Window('演示',layout)

while True:
    event, values = window.read()
    if event == None:
        break
    if event == '確認':
        if values['-SD-'] > 7.0:
            print('PH:',values['-SD-'],'鹼性')
            window['-TEXT-'].update('ph:'+str(values['-SD-'])+' 鹼性')
        if values['-SD-'] < 7.0:
            print('PH:',values['-SD-'],'酸性')
            window['-TEXT-'].update('ph:' + str(values['-SD-']) + ' 酸性')
        elif values['-SD-'] == 7.0:
            print('PH:',values['-SD-'],'中性')
            window['-TEXT-'].update('ph:' + str(values['-SD-']) + ' 中性')
    if event == '重置':
        window['-SD-'].update(value=7.0)
    if event =='上調':
        flag=values['-SD-']
        flag=flag+0.1
        window['-SD-'].update(value=flag
        )
    if event =='下調':
        flag=values['-SD-']
        flag=flag-0.1
        window['-SD-'].update(value=flag
        )

window.close()

7.22 紅綠燈

import threading
import time
import PySimpleGUI as sg

def update_button(window, key, color):
    window[key].update(button_color=('black', color))

def traffic_light_controller(window):
    while True:
        update_button(window, '-G-', 'green')
        update_button(window, '-Y-', 'gray')
        update_button(window, '-R-', 'gray')
        for seconds in range(30, 0, -1):
            window['-TIMER-'].update(seconds)
            time.sleep(1)

        update_button(window, '-G-', 'gray')
        update_button(window, '-Y-', 'yellow')
        update_button(window, '-R-', 'gray')
        window['-TIMER-'].update('')
        time.sleep(5)

        update_button(window, '-G-', 'gray')
        update_button(window, '-Y-', 'gray')
        update_button(window, '-R-', 'red')
        for seconds in range(30, 0, -1):
            window['-TIMER-'].update(seconds)
            time.sleep(1)


layout = [
    [sg.Text('計時器:', size=(15, 1)), sg.Text('', size=(5, 1), key='-TIMER-')],
    [sg.B(button_text='綠燈', button_color=('black', 'gray'), size=(20, 10), key='-G-')],
    [sg.B(button_text='黃燈', button_color=('black', 'gray'), size=(20, 10), key='-Y-')],
    [sg.B(button_text='紅燈', button_color=('black', 'gray'), size=(20, 10), key='-R-')]
]

window = sg.Window('交通訊號燈', layout, finalize=True)

# 建立並啟動執行緒
controller_thread = threading.Thread(target=traffic_light_controller, args=(window,), daemon=True)
controller_thread.start()

while True:
    event, values = window.read(timeout=1000)  # Timeout in milliseconds, 1000ms = 1 second

    if event == sg.WINDOW_CLOSED:
        break

# 關閉視窗
window.close()

7.23 選單

import PySimpleGUI as sg
def Gui():
    menu_def = [['File(&F)', ['New', 'Open', '!Save', 'Exit', ]],
                ['Edit', ['Cut', 'Copy::CP', 'Paste', 'Undo'], ],
                ['Help', 'About...'], ]
    right_menu = [['&File', ['&New', '']]]
    layout = [[sg.Menu(menu_def)],
          [sg.Multiline("", key='-IN-',
                         expand_x=True, expand_y=True)],
          [sg.Multiline("", key='-OUT-',
                         expand_x=True, expand_y=True)],
          [sg.Text("", key='-TXT-',
                    expand_x=True, font=("Arial Bold", 14))],
          ]
    window = sg.Window("Menu", layout, size=(715, 300))
    while True:
        event, values = window.read()
        print(event, values)

        if event != sg.WIN_CLOSED:
            window['-TXT-'].update(values[0] + "Menu Button Clicked")
        if event == 'Copy::CP':
            txt = window['-IN-'].get()
        if event == 'Paste':
            window['-OUT-'].update(value=txt)
        if event == sg.WIN_CLOSED:
            break
    window.close()
Gui()

7.24 表格

import PySimpleGUI as sg
a=['編號','商品','價格','','','','']
b=[['001','牛奶','5'],['002','蘋果','6'],['003','香菸','10']]
layout=[[sg.Table(b,#表格內容
                  headings=a,#表格頭部
                  max_col_width=500,#所有列最大寬度
                  auto_size_columns=False,#是否自動適應列寬度
                  def_col_width=10,#定義列表寬度
                  display_row_numbers=True,#是否顯示序號列
                  justification='c',#對齊方式
                  num_rows=15,#定義行數
                  row_height=30,
                  key='-a-',
                  font=('黑體',10),
                  text_color='black',
                  background_color='Light blue',
                  enable_events=True,
                  bind_return_key=True
                  )]]

window=sg.Window('表格',layout)
while True:
    event, values = window.read()
    if event ==None:
        break

window.close()

7.25 計算器

import PySimpleGUI as sg
def button(text):
    return sg.B(text,size=(5,3),font=('黑體',18),button_color='black')

layout = [[sg.ML(size=(15,2), key='-IN-',font=('黑體',28))],
          [sg.T('結果',font=('黑體',12)),sg.In(key='-OUT-',size=(13,1),font=('黑體',28))],
        [button(i) for i in ['AC','(',')','%']],
        [button(i) for i in '123+'],
          [button(i) for i in '456-'],
          [button(i) for i in '789×'],
          [button(i) for i in '0.=÷'],

          ]

window = sg.Window('計算器',layout)
x=None
y=None

while True:

        event, values = window.read()
        if event ==None:
            break
        if event in list('1234567890+-().'):
            window['-IN-'].update(values['-IN-']+event)
        if event == '%':
            try:
                a=eval(values['-IN-']+'*0.01')
                window['-IN-'].update(values['-IN-'] + '*0.01')
            except:
                window['-IN-'].update('')
                sg.popup('輸入有誤')
        if event == '×':
            window['-IN-'].update(values['-IN-'] + '*')
        if event == '÷':
            window['-IN-'].update(values['-IN-'] + '/')
        if event == 'AC':
            window['-IN-'].update('')
            window['-OUT-'].update('')

        if event == '=':
            try:
                window['-OUT-'].update(eval(values['-IN-']))
            except Exception as e:
                sg.popup('請輸入合法的表示式')
                print('錯誤報告:',e)

window.close()

7.26 設定模板主題

import PySimpleGUI as sg

print(sg.theme_list())
sg.theme('DarkRed')
sg.Popup('彈窗演示')
# print(sg.theme_button_color())
sg.theme_button_color(('black', '#ad1d45'))
sg.Popup('演示彈窗','按鍵字型變黑色')

7.27 呼叫字典

import PySimpleGUI as sg

dict ={'河南':'鄭州','河北':'石家莊','浙江':'杭州','湖北':'武漢'}
list = []
for i in dict:
    list.append(i)
layout = [[sg.LB(list,key='-DICT-',size=(40,3),enable_events=True)],
          [sg.T('行政中心'),sg.Input(key='-INPUT-',size=(30))]]
window = sg.Window('演示',layout)


while True:
    event, values =window.read()
    if event == None:
        break
    if event == '-DICT-':
        window['-INPUT-'].update(dict[values['-DICT-'][0]])


window.close()

7.28 選擇選單和旋轉按鈕

import PySimpleGUI as sg

list = ['Python', 'Java', 'C++', 'JavaScript', 'php']
layout = [[sg.Text('OptionMenu'),sg.OptionMenu(list,key='-OM-'),
           sg.Text('Spin'),sg.Spin(list,size=(10,1),key='-SP-',enable_events=True)],
          [sg.Text('語言'),sg.In(key='-IN-',size=(25))]]

window = sg.Window('演示介面',layout)
while True:
    event, values =window.read()
    if event ==None:
        break
    if event == '-OM-' or event =='-SP-':
        window['-IN-'].update(values['-SP-'])
window.close()

7.29顏色選擇器和日曆選擇

import PySimpleGUI as sg

month =['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月']
week = ['週日','週一','週二','週三','週四','週五','週六']

layout = [[sg.ColorChooserButton(button_text='顏色選擇器'),sg.In()],
          [sg.CalendarButton(button_text='日曆選擇器',
                             close_when_date_chosen=False,
                             # default_date_m_d_y=None,
                            # locale='',
                            format='%Y年%m月%d日',
                            begin_at_sunday_plus=1,
                             month_names=month,
                             day_abbreviations=week,
                             title='日曆',
                             no_titlebar=False,
                             location=(700,500),
                             ),sg.In()]]

window = sg.Window('',layout)
while True:
    event, values = window.read()
    if event == None:
        break

window.close()

7.30 PDF合併工具

import PySimpleGUI as sg
import os
from PyPDF2 import PdfFileReader, PdfFileWriter, PdfWriter, PdfReader


def FileNameGet(filedir):
    files_list = [os.path.join(root,filepath) \
                  for root, dirs, files in os.walk(filedir) \
                  for filepath in files\
                  if str(filepath).endswith('pdf')]
    return files_list if files_list else[]

def PDFMerge(filepath,output_file):
    output = PdfWriter()
    output_pages = 0
    pdf_file_name = FileNameGet(filepath)

    if pdf_file_name:
        for pdf_file in pdf_file_name:
            sg.cprint("路徑:%s" % pdf_file)
            #讀取源PDF檔案
            input=PdfReader(open(pdf_file,"rb"))
            #獲得源PDF檔案中頁面頁數
            page_count = len(input.pages)
            output_pages += page_count
            sg.cprint("頁數:%d" % page_count)
            #分別將page新增到輸出output中
            for iPage in range(page_count):
                output.add_page(input.pages[iPage])
        sg.cprint("合併後的總頁數:%d." % output_pages)
        output_stream = open(os.path.join(filepath,output_file),"wb")
        try:
            output.write(output_stream)
            output_stream.close()
        except Exception as e:
            sg.cprint("合併失敗,請重試")

        sg.cprint("PDF檔案合併完成!")
        sg.cprint(f"合併後的檔案路徑:{filepath}/{output_file}",)
    else:
        sg.cprint("沒有可以合併的PDF檔案")
#GUI
def main():
    layout = [[sg.Text('選擇資料夾:',size=(15,1)),sg.In(size=(40,1),key='-file_dir-'),sg.FolderBrowse()],
              [sg.Text('輸入合併後的檔名:',size=(15,1)),sg.In(size=(40,1),key='-out_file-'),sg.B('開始合併')],
              [sg.ML(size=(70,15),reroute_cprint=True)]
              ]

    window = sg.Window('PDF合併工具',layout)
    while True:
        event, values = window.read()
        file_dir = values['-file_dir-']
        out_file = values['-out_file-']
        if event ==None:
            break
        if event == '開始合併':
            PDFMerge(file_dir,out_file)

    window.close()
main()

8 資源連結

PySimpleGUI 官方文件

PySimpleGUI GitHub

作者:TheHypocrite