6 Mayıs 2020 Çarşamba

PySimpleGUI ile KOLAY PYTHON GUI - 2

<< 1. Bölüm 

Merhaba,

Geçen bölüm kaldığımız yerden devam ediyoruz. Yeni bir reçete ile başlıyoruz.



Reçete - Program ayarlarını kaydetmek ve yüklemek


Bazı programlar son durumunu ya da bazı ayarlarını saklayıp sonraki kullanımda tekrar aynı yerlerden devam etme ihtiyacı duyar. 

Bu program reçete olarak biraz uzun ama bize bir çok fikir verecek.

Ana düşüncemiz programa ait ayarları bir dictionary'de saklamak. Bu dictionary diske kaydedilecek ve oradan yüklenecek. 

Bu özelliğe ihtiyaç duyan uygulamalardan biri rainmeter stili dediğimiz görsellikte olan uygulamalar. Bu küçük programlar her zaman bir ayarları kaydetme ihtiyacı duyarlar. 

Yapı oldukça basit. Ayarlarımızı bir dictionary'ye koyarız. GUI ayarlarında yapılan değişiklikler bu dictionary'yi değiştirir ve daha sonra tekrar kullanmak üzere diske kaydederiz. Böylece programı her açtığımızda tekrar aynı ayarlamaları yapmak zorunda kalmayız.

Verileri kayıt/yükleme için kullanacağımız paket bir JSON paketi olacak. Bunlar Python dictionary'lerini yazmayı ve okumayı çok kolay kılar. Ayrıca oluşan dosyaları manual olarak da çok kolay değiştirebiliriz. 

Bu raçete tarifinde programımızı şöyle düzenlememiz gerekiyor.
  1. Default ayarlar en üstte olacak
  2. Key ve değerlerden oluşan bir tablo hazırlayacağız
  3. Ayarlar dosyası adı
  4. Ayarlar penceresi
  5. Ana program
Basit bir ana program penceresinde "Ayarları Değiştir" butonu ekleyelim.


Daha önemli pencereyse ayarlar penceresi


Pencereleri metodlar içinde tanımlayıp her seferinde yeniden üretilmesini sağlayan bir kod ile uygulama kodu şöyle olacaktır.


ChangeSettings.py
import PySimpleGUI as sg
from json import (load as jsonload, dump as jsondump)
from os import path

"""
    Basit bir "ayarlar" uygulaması. Programınızın ayarlarını 
    yükler/düzenler/kaydeder. JSON dosya formatı ile ayarlar kaydedilir.
    Eğer bir dictionary'ye değer yazabiliyorsanız kolayca diske de 
    kaydedebilirsiniz.

    Copyright 2020 PySimpleGUI.com
    Licensed under LGPL-3
"""

SETTINGS_FILE = path.join(path.dirname(__file__), r'settings_file.cfg')
DEFAULT_SETTINGS = {"max_users": 10, "user_data_folder": None, 
                    "theme": sg.theme(), "zipcode": "94102"}
# ayarların dictionary keylerini penceredeki eleman keylerine eşleştir
SETTINGS_KEYS_TO_ELEMENT_KEYS = {"max_users": "-MAX USERS-", "user_data_folder": "-USER FOLDER-",
            "theme": "-THEME-", "zipcode": "-ZIPCODE-"}


############### Ayarlar dosyasını kaydet/yükle ###############
def load_settings(settings_file, default_settings):
    try:
        with open(settings_file, 'r') as f:
            settings = jsonload(f)
    except Exception as e:
        sg.popup_quick_message(f"exception {e}", "Ayarlar dosyası bulunamadı... yenisi tanımlanacak", keep_on_top=True, background_color="red", text_color="white")
        settings = default_settings
        save_settings(settings_file, settings, None)
    return settings

def save_settings(settings_file, settings, values):
    if values:      # values değeri varsa değerler pencereden gelmiştir
        for key in SETTINGS_KEYS_TO_ELEMENT_KEYS:
            try:
                settings[key] = values[SETTINGS_KEYS_TO_ELEMENT_KEYS[key]]
            except Exception as e:
                print(f"Ayarları pencere değerlerinden yükleme hatası. Key = {key}")
    
    with open(settings_file, 'w') as f:
        jsondump(settings, f)
    sg.popup("Ayarlar kaydedildi")


############### ayarlar penceresi ##############
def create_settings_window(settings):
    sg.theme(settings["theme"])

    def TextLabel(text): return sg.Text(text+":", justification="r", size=(15, 1))

    layout = [   [sg.Text("Ayarlar", font="Any 15")],
        [TextLabel("Max Kullanıcı"), sg.Input(key="-MAX USERS-")],
        [TextLabel("Klasör"), sg.Input(key="-USER FOLDER-"), sg.FolderBrowse(target="-USER FOLDER-")],
        [TextLabel("Zip kodu"), sg.Input(key="-ZIPCODE-")],
        [TextLabel("Tema"), sg.Combo(sg.theme_list(), size=(20, 20), key="-THEME-")],
        [sg.Save(), sg.Exit()]   ]

    window = sg.Window("Ayarlar", layout, keep_on_top=True, finalize=True)

    for key in SETTINGS_KEYS_TO_ELEMENT_KEYS:
        try:
            window[SETTINGS_KEYS_TO_ELEMENT_KEYS[key]].update(value=settings[key])
        except Exception as e:
            print(f"Ayarlardan uygulamaya alırken hata. Key = {key}")

    return window


############### Ana program ###############
def create_main_window(settings):
    sg.theme(settings["theme"])

    layout = [   [sg.Text("Bu ana uygulama penceresi")],
            [sg.Text("Ana pencere elemanlarını buraya koyun")],
            [sg.Ok(), sg.Exit(), sg.Button("Ayarları Değiştir")]   ]
    
    return sg.Window("Ana Pencere", layout)


def main():
    window, settings = None, load_settings(SETTINGS_FILE, DEFAULT_SETTINGS)

    while True:
        if window is None:
            window = create_main_window(settings)

        event, values = window.read()
        if event in (None, "Exit"):
            break
        if event == "Ayarları Değiştir":
            event, values = create_settings_window(settings).read(close=True)
            if event == "Save":
                window.close()
                window = None
                save_settings(SETTINGS_FILE, settings, values)

    window.close()

main()




Reçete - Dosya seçimi yaptırmak


Bazen birden fazla dosya ismi sormamız gerekebilir. Aşağıdaki uygulamada 2 dosya ismi isteniyor ve sonra bunlar karşılaştırılıyor. Input elemanlarını kullanarak yapılan uygulamada kullanıcı isterse Browse butonu yardımıyla dosya seçimi yapıyor, isterse dosya adresini kopyalayıp direk olarak Input'lara yapıştırabiliyor.


GetFiles.py
import PySimpleGUI as sg

sg.theme("LightBlue2")

layout = [   [sg.Text("Karşılaştırmak için 2 dosya giriniz")],
            [sg.Text("Dosya 1", size=(8, 1)), sg.Input(), sg.FileBrowse()],
            [sg.Text("Dosya 2", size=(8, 1)), sg.Input(), sg.FileBrowse()],
            [sg.Submit(), sg.Cancel()]   ]

window = sg.Window("Dosya Karşılaştırma", layout)

event, values = window.read()
window.close()
print(f"{event} tıkladınız")
print(f"{values[0]} ve {values[1]} dosyalarını seçtiniz")

Bu şablon kullanıcıdan bir dosya ya da klasör seçmesini isterken çok kullanışlıdır. Bir Input elemanı ve yanına bir Browse butonu koyarak işimizi basitçe hallediyoruz. Input elemanı kullanarak kullanıcıya dosya adresini kopyalayıp yapıştırma imkanı da sağlamış oluyoruz.



Reçete - Input elemanı kullanmadan dosya ismi almak



Girilen değeri göstermek istemediğimizde kolayca Input elemanını görünmez yaparak bunu gerçekleştirebiliriz. Bu kodun yazdırma satırında event değerini de yazdırırsak "-FILE-" olayının gerçekleştiğini görürüz.Browse butonu ile seçilen dosya adresi Input elemanın içeriğini değiştirince olay tetiklenir.

GetFile2.py
import PySimpleGUI as sg

sg.theme("DarkRed")

layout = [   [sg.Text("Bir dosya seçin")],
            [sg.Input(key="-FILE-", visible=False, enable_events=True), sg.FileBrowse()]   
        ]

event, values = sg.Window("Dosya Seçimi", layout).read(close=True)

print(f"{values['-FILE-']} seçtiniz, event {event}")




Reçete - Tüm elemanlar bir arada


Hemen tüm elemanların olduğu bir pencere yaparsak ilerde bize çok yardımcı olur. Uygulamamızda kullanıcı renk şeması, birçok eleman, default değerler, sütunlar, renkli yazılı çerçeveler, tooltip, dosya seçimi var. 

Aşağıda koda bakmadan önce böyle bir uygulama için kaç satır kod yazmak gerekir bir tahmin yapın.


import PySimpleGUI as sg

sg.ChangeLookAndFeel("GreenTan")

# ---------- menü tanımlaması ---------- #
menu_def = [   ["Dosya", ["Aç", "Kaydet", "Çıkış", "Özellikler"]],
            ["Düzenle", ["Yapıştır", ["Özel", "Normal"], "Geri Al"]],
            ["Yardım", "Hakkında..."]   ]

# ---------- Column tanımlaması ---------- #
column1 = [[sg.Text("Sütun 1", background_color="#f7f3ec", justification="center", size=(10, 1))],
        [sg.Spin(values=("Spin Box 1", "Spin Box 2", "Spin Box 3"), initial_value="Spin Box 1")],
        [sg.Spin(values=("Spin Box 1", "Spin Box 2", "Spin Box 3"), initial_value="Spin Box 2")],
        [sg.Spin(values=("Spin Box 1", "Spin Box 2", "Spin Box 3"), initial_value="Spin Box 3")]
        ]
layout = [   
    [sg.Menu(menu_def, tearoff=True)],
    [sg.Text("Tüm grafik zımbırtılar tek pencerede!", size=(30, 1), justification="center", font=("Helvetica", 25), relief=sg.RELIEF_RIDGE)],
    [sg.Text("Burada biraz yazı var... ve yazı girmek için bir yer")],
    [sg.InputText("Bu bana ait bir yazı")],
    [sg.Frame(layout=[
        [sg.Checkbox("Checkbox", size=(10, 1)), sg.Checkbox("İkinci Checkbox", default=True)],
        [sg.Radio("İlk Radio buton", "RADIO1", default=True, size=(10, 1)), sg.Radio("İkinci Radio buton", "RADIO1")]
    ], title="Opsiyonlar", title_color="red", relief=sg.RELIEF_SUNKEN, tooltip="Flag setlemek için bunları kullanın")],
    [sg.Multiline(default_text="Bu default yazı, bir şey yazmasanız da olur", size=(35, 3)),
        sg.Multiline(default_text="İkinci bir Multiline", size=(35, 3))],
    [sg.InputCombo(("Combobox 1", "Combobox 2"), size=(20, 1)),
        sg.Slider(range=(1, 100), orientation="h", size=(34, 20), default_value=85)],
    [sg.InputOptionMenu(("Menü opsiyonu 1", "Menü opsiyonu 2", "Menü opsiyonu 3"))],
    [sg.Listbox(values=("Listbox 1", "Listbox 2", "Listbox 3"), size=(30, 3)),
        sg.Frame("Etiketlenmiş Grup", [[
            sg.Slider(range=(0, 100), orientation="v", size=(5, 20), default_value=25),
            sg.Slider(range=(0, 100), orientation="v", size=(5, 20), default_value=75),
            sg.Slider(range=(0, 100), orientation="v", size=(5, 20), default_value=10),
            sg.Column(column1, background_color="#f7f3ec")
        ]])],
    [sg.Text("_" * 80)],
    [sg.Text("Bir klasör seçin", size=(35, 1))],
    [sg.Text("Klasörünüz", size=(15, 1), auto_size_text=False, justification="right"),
        sg.InputText("Default klasör"), sg.FolderBrowse()],
    [sg.Submit(tooltip="Bu pencereyi göndermek için tıklayın"), sg.Cancel()]   
]

window = sg.Window("Her şey birarada", layout, default_element_size=(40, 1), grab_anywhere=False)

event, values = window.read()

sg.popup("Title", 
    " Pencerenin cevabı.", 
    " Basılan buton : '{}'".format(event),
    " Değerler :", values)


35 satır ve rahat anlaşılabilen bir kod. Diğer Python GUI kütüphaneleri ile yanına bile yaklaşılamaz kadar kısa bir program. 




Periyodik Güncellemeli Asenkron Pencere


PySimpleGUI programlarımızı asenkron modda çalıştırmak için belki de daha kolay bir yol var. 

İyi de bu ne demek?

2 çeşit çalışma modu var sync ve async çalışma. Şimdiye kadar gördüğümüz senkron modda GUI çizilir ve bir olay olana kadar window.read() metodu ile beklenir. 

Asenkron modda ise bir olayın gerçekleşmesini veya belli bir zaman geçmesini bekler , zaman dolduğunda bir olay gerçekleşmese de geri dönülür. Programımız sadece kullanıcının etkileşimini bekleyecek değil , bu arada başka işleri de kovalamamız gerekebilir. (Haydaa şimdiye kadar anlatılanlar çöpe mi gitti?). 

Asenkron modda çalışınca sanki bir çok işlem aynı anda oluyormuş gibi izlenim oluşuyor. 

Yani, programımızın akışı kullanıcı etkileşim yapmazken bloklanmıyor ya da durdurulmuyor. Program kullanıcı lay lay yaparken çalışmaya ve diğer işlerle ilgilenmeye devam ediyor. 

Asenkron çalışmanın kritik parçası ise başka şeylere dalıp bu sefer de read() veya refresh() metodlarını yeteri sıklıkta kullanmayı unutmamalıyız. Kodumuzun çalışıyor olması GUI'yi sallamayacağız anlamına gelmiyor. GUI kilitlendiğinde ne olduğunu biliriz. Kimse şu sevimli pencere ile karşılaşmak istemez:


Bu olay, GUI alt sistemine uzun süre çalışma izni vermeyince oluşur. Olay döngünüze bir sleep komutu eklemek bunlardan birini çıkarmakta baya başarılı olacaktır. 



Sorgulama yapan asenkron


Butasarımda olan uygulamalar bir şeyleri düzenli olarak sorgular ya da çıktı verirler. Aşağıdaki uygulamamızda daha önce bir örneğini gördüğümüz gibi read() metoduna timeot=10 parametresi veriyoruz. Bu herhangi bir olay gerçekleşmese de 10 mili saniyeden sonra satırdan çıkar. 

timeout kullanan pencere programları yazarken dikkat etmemiz gereken bir nokta var. Ne yaptığımızdan çok emin olmadıktan sonra timeout=0 parametresi kullanmak sıkıntılı sonuçlar doğurabilir. Bu şekilde programı sürekli bir döngü içine sokarız. Bu CPU çekirdeğini %100 meşgul ederek istenmeyen sonuçlar doğurabilir.

Bir kısa not da program hakkında. Kronometre benzeri uygulamalar yaparken bu şekilde döngüler değil de sistem saatinden alınan veri kullanılmalıdır. Döngülerde mutlaka zaman kaymaları olacaktır. Burada yaptığımız sadece konuyla alakalı bir örnek yapmak içindir.


Async.py
import PySimpleGUI as sg

sg.theme("DarkBrown1")

layout = [  [sg.Text("Kronometre", size=(20, 2), justification="center")],
            [sg.Text(size=(10, 2), font=("Helvetica", 20), justification="center", key="-OUTPUT-")],
            [sg.T(" "*5), sg.Button("Start/Stop", focus=True), sg.Quit()]  ]

window = sg.Window("Zamanlayıcı", layout)

timer_running, counter = False, 0

while True:
    event, values = window.read(timeout=10)
    if event in (None, "Quit"):
        break
    elif event == "Start/Stop":
        timer_running = not timer_running
    if timer_running:
        window["-OUTPUT-"].update("{:02d}:{:02d}:{:02d}".format((counter//100)//60, (counter//100)%60, counter%100))
        counter += 1

window.close()

Butonun focus parametresi uygulamanın o buton seçili olarak başlamasını sağlıyor. Böylece mouse kullanmadan enter ya da boşluk çubuğuyla kronometreyi başlatıp durdurabiliriz.



Görev fonksiyonu simülasyonu


Bazı programların yapılarında butonların işlevlerini satır arası kodlarla işlemek yerine buton görev fonksiyonları kullanmak, özellikle programın okunabilirliği açısından faydalıdır. Birçok GUI sisteminde görev fonksiyonları yapısı vardır.. PySimpleGUI'de de görev fonksiyonları uygulaması şöyle yapılır. 


Callback.py
import PySimpleGUI as sg

sg.theme("LightBlue3")

# Görev fonksiyonları
def button1():
    print("Buton 1 görev fonksiyonu")

def button2():
    print("Buton 2 görev fonksiyonu")

# butonları fonksiyonlara eşleyen dictionary
dispatch_dictioanary = { "1": button1, "2": button2 }

layout = [  [sg.Text("Bir butona tıklayın", auto_size_text=True)],
            [sg.Button("1"), sg.Button("2"), sg.Button("3"), sg.Quit()]  ]

window = sg.Window("Buton görev örneği", layout)

while True:
    event, values = window.read()
    if event in (None, "Quit"):
        break
    # butonungörev fonksiyonu var mı?
    if event in dispatch_dictioanary:
        func_to_call = dispatch_dictioanary[event]
        func_to_call()
    else:
        print("{} olayı görev fonksiyon listesinde yok".format(event))

window.close()




Reçete - OneLineProgressMeter


Bu reçetede tek satır kod ile ProgressMeter elemanı tanımlamasını göreceğiz.


OneLineProgressMeter.py
import PySimpleGUI as sg

sg.theme("DarkBlue8")

for i in range(1000): # bu izlemek istediğimiz olayın içinde olduğu döngü
    sg.OneLineProgressMeter("Tek satır progress örneği", i+1, 1000, "key")

Diğer paketlerdeki progress metrelerin aksine PySimpleGUI'de ProgressMeter sadece 1 satır koddur 2 değil. Eskiden progres metreler iş yapan döngünün dışında tanımlanır, döngü içinde değerleri güncellenirdi. Burada herşey döngü içinde gerçekleşiyor. Olası opsiyonlar için dökümana bakınız.




Reçete -Mayın tarlası stili butonlardan grid


Bir çok uygulama butonlardan bir grid şeklinde tasarımlar kullanır. Mayın tarlası ve amiral battı oyunları bu butonlara en güzel örneklerden. 


Yukarıdaki pencerenin kodu şöyle:

Minesweeper.py
import PySimpleGUI as sg
from random import randint

MAX_ROWS = MAX_COLS = 10
board = [[randint(0,1) for j in range(MAX_COLS)] for i in range(MAX_ROWS)]

layout = [[sg.Button("?", size=(4, 2), key=(i, j), pad=(0, 0)) for j in range(MAX_COLS)] for i in range(MAX_ROWS)]

window = sg.Window("MAyın Tarlası", layout)

while True:
    event, values = window.read()
    if event == None:
        break
    window[event].update(board[event[0]][event[1]], button_color=("white", "black"))

window.close()

Bu koddan öğreneceğimiz en önemli şey key ve event değerleri ille de string olmak zorunda değil mesela burada değerler satır ve sütun değerini veren tamsayı tuple olmuş. Böylece butonlar kolayca adreslenebilmiş.

Bu program PySimpleGUIWeb kütüphanesi ile de çalışır. Eğer PySimpleGUIWeb yüklersek ve import satırında PySimpleGUI yerine PySimpleGUIWeb yazarsak aynı uygulamayı tarayıcıda görürüz.







Reçete - Grafikli butonlar (Media Player)


Butonların PNG veyaGIF resim dosyasını grafik olarak alabileceğini görmüştük. Bu medya player örneği de 4 grafik butona sahip. Buton arkaplanları ve uygulama arkaplanı aynı renk yapılarak sanki butonun şekli dikdörtgen değil de grafiğin şeklindeymiş gibi izlenim yapıyor. 



MediaPlayer.py
import PySimpleGUI as sg

#
# bir media player'ın asenkron tasarımı
# güzel bir görüntü için butonlarda grafik kullanıyor
#
def MediaPlayerGUI():
    background = "#f0f0f0"
    sg.theme("LightBlue3")

    # uygulama ve eleman arkaplanlarını aynı renk yapalım
    sg.SetOptions(background_color=background, 
        element_background_color=background,
        text_element_background_color=background)

    image_pause = "images/Pause.png"
    image_restart = "images/Restart.png"
    image_next = "images/Next.png"
    image_exit = "images/Exit.png"

    # yerleşimdeki bir Text elemanı çıktıları yazdırma amaçlı kullanılacak

    layout = [  [sg.Text("Medya Dosyası Oynatıcı", size=(22, 1), font=("Helvetica", 25))],
                [sg.Text(size=(15, 2), font=("Helvetica", 14), key="-OUTPUT-")],
                [sg.Button("", button_color=(background, background),
                    image_filename=image_restart,
                    image_subsample=2, border_width=0, key="Restart Song"),
                    sg.Text(" "*2),
                sg.Button("", button_color=(background, background),
                    image_filename=image_pause,
                    image_subsample=2, border_width=0, key="Pause"),
                    sg.Text(" "*2),
                sg.Button("", button_color=(background, background),
                    image_filename=image_next,
                    image_subsample=2, border_width=0, key="Next"),
                    sg.Text(" "*2),
                sg.Button("", button_color=(background, background),
                    image_filename=image_exit,
                    image_subsample=2, border_width=0, key="Exit")],
                [sg.Text("_"*22)],
                [sg.Text(" "*30)],
                [
                    sg.Slider(range=(-10, 10), default_value=0, size=(5, 20), orientation="v", font=("Helvetica", 15)),
                    sg.Text(" "*2),
                    sg.Slider(range=(-10, 10), default_value=0, size=(5, 20), orientation="v", font=("Helvetica", 15)),
                    sg.Text(" "*2),
                    sg.Slider(range=(-10, 10), default_value=0, size=(5, 20), orientation="v", font=("Helvetica", 15)),
                ],
                [
                    sg.Text("   Bass", font=("Helvetica", 15), size=(9, 1)),
                    sg.Text("Treble", font=("Helvetica", 15), size=(7, 1)),
                    sg.Text("Volume", font=("Helvetica", 15), size=(7, 1)),
                ]
            ]

    window = sg.Window("Medya Dosya Oynatıcı", layout, default_element_size=(20, 1),
        font=("Helvetica", 25))

    while True:
        event, values = window.read(timeout=100)
        if event in (None, "Exit"):
            break
        # eğer buton basıldıysa bilgi satırında göster
        if event != sg.TIMEOUT_KEY:
            window["-OUTPUT-"].update(event)

    window.close()

MediaPlayerGUI()

Resimleri de vereyim









Reçete - Script çalıştırıcı - Kalıcı pencere


Bu pencere buton tıklaması sonrası kapanmaz. ÇIKIŞ butonunun dışında tabii ki. Bu pencere komutları çalıştırır ve sonuçlarını kaydırılabilir bir pencerede gösterir.


ScriptLauncher.py
import PySimpleGUI as sg
import subprocess as subp

def ExecuteCommandSubprocess(command, *args):
    try:
        sp = subp.Popen([command, *args], shell=True, stdout=subp.PIPE, stderr=subp.PIPE)
        out, err = sp.communicate()
        if out:
            print(out.decode("utf-8"))
        if err:
            print(err.decode("utf-8"))
    except:
        pass

layout = [
    [sg.Text("Script çıktısı....", size=(40, 1))],
    [sg.Output(size=(80, 20))],
    [sg.Button("script1"), sg.Button("script2"), sg.Button("Çıkış")],
    [sg.Text("Manual komut", size=(15, 1)), sg.InputText(focus=True), sg.Button("Run", bind_return_key=True)]
]

window = sg.Window("Script çalıştırıcı", layout)

# ----====---- Kullanıcı girişini alan ve onu scriptleri çağırmakta kullanan döngü ---- #

while True:
    event, value = window.read()
    if event == "Çıkış" or event is None:
        break
    if event == "script1":
        ExecuteCommandSubprocess("pip", "list")
    elif event == "script2":
        ExecuteCommandSubprocess("python", "--version")
    elif event == "Run":
        ExecuteCommandSubprocess(value[0])

window.close()




Reçete - Buton tıklamasıyla uygulama çalıştırma


Bir dış programa subprocess ile ulaşan bir program. Masaüstü uygulamalara erişim için toolbar yapmakta çok faydalı olacaktır.

ButtonLauncher.py
import PySimpleGUI as sg
import subprocess

CHROME = r"C:\Program Files\Google\Chrome\Application\chrome.exe"

layout = [
    [sg.Text("Text area", key="-TEXT-")],
    [sg.Input(key="-URL-")],
    [sg.Button("Chrome"), sg.Button("Çıkış")]
]

window = sg.Window("Title", layout)

while True:
    event, values = window.read()
    print(event, values)
    if event in (None, "Çıkış"):
        break
    if event == "Chrome":
        sp = subprocess.Popen([CHROME, values["-URL-"]], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

window.close()





Reçete - Machine Learning GUI


Yapay zeka falan havalı kelimeler , bu uygulamada bir çok eleman var.



MachineLearning.py
import PySimpleGUI as sg

sg.theme("GreenTan")

sg.SetOptions(text_justification="right")

layout = [
    [sg.Text("Makina öğrenimi komut satırı parametreleri", font=("Helvetica", 16))],
    [sg.Text("Denemeler", size=(15, 1)), sg.Spin(values=[i for i in range(1, 1000)], initial_value=20, size=(6, 1)),
     sg.Text("Adımlar", size=(18, 1)), sg.Spin(values=[i for i in range(1, 1000)], initial_value=20, size=(6, 1))],
    [sg.Text("ooa", size=(15, 1)), sg.In(default_text="6", size=(10, 1)), sg.Text("nn", size=(15, 1)),
     sg.In(default_text="10", size=(10, 1))],
    [sg.Text("q", size=(15, 1)), sg.In(default_text="ff", size=(10, 1)), sg.Text("ngram", size=(15, 1)),
     sg.In(default_text="5", size=(10, 1))],
    [sg.Text("l", size=(15, 1)), sg.In(default_text="0.4", size=(10, 1)), sg.Text("Layers", size=(15, 1)),
     sg.Drop(values=("BatchNorm", "other"), auto_size_text=True)],
    [sg.Text("_"*100, size=(67, 1))],
    [sg.Text("Flags", font=("Helvetica", 15), justification="left")],
    [sg.Checkbox("Normalize", size=(12, 1), default=True), sg.Checkbox("Verbose", size=(20, 1))],
    [sg.Checkbox("Cluster", size=(12, 1)), sg.Checkbox("Flush output", size=(20, 1), default=True)],
    [sg.Checkbox("Write results", size=(12, 1)), sg.Checkbox("Keep Intermediate Data", size=(20, 1))],
    [sg.Text("_"*100, size=(67, 1))],
    [sg.Text("Loss function", font=("Helvetica", 15), justification="left")],
    [sg.Radio("Cross-Entropy", "loss", size=(12, 1)), sg.Radio("Logistic", "loss", size=(12, 1))],
    [sg.Radio("Hinge", "loss", size=(12, 1)), sg.Radio("Huber", "loss", size=(12, 1))],
    [sg.Radio("Kullerback", "loss", size=(12, 1)), sg.Radio("MAE(L1)", "loss", size=(12, 1))],
    [sg.Radio("MSE(L2)", "loss", size=(12, 1)), sg.Radio("M8(L0)", "loss", size=(12, 1))],
    [sg.Submit(), sg.Cancel()]
]

window = sg.Window("Makina öğrenimi görseli", layout, font=("Helvetica", 12))

event, values = window.read()

Sadece örnek olsun diye verilmiş bir GUI örneği..



Bu bölüm çok uzadı. Bu kadarıyla bir yayınlayalım, gerisini sonraki bölümde bitiririz inşallah. Görüşmek üzere kalın sağlıcakla..

<< 1. Bölüm 


Hiç yorum yok:

Yorum Gönder