6 Mayıs 2020 Çarşamba

PySimpleGUI ile KOLAY PYTHON GUI - 3

<< 2. Bölüm

Merhaba. Devam edelim. Önceki iki bölümden sonra örnek GUI reçeteleri ile devam ediyoruz.



Reçete - Ismarlama Progressbar


Daha önce bir progressbar görmüştük ama onunyanında bir sürü istatistiki bilgi de vardı. Kendi isteğimize özel görünümde bir progressbar elde etmek için bu reçeteyi kullanabiliriz. 


CustomProgressbar.py
import PySimpleGUI as sg

layout = [  [sg.Text("Bir ısmarlama progres metre")],
            [sg.ProgressBar(1000, orientation="h", size=(20, 20), key="-PROGBAR-")],
            [sg.Cancel()]  ]

window = sg.Window("Ismarlama progressbar", layout)

for i in range(1000):
    event, values = window.read(timeout=0)
    if event in (None, "Cancel"):
        break
    window["-PROGBAR-"].update_bar(i + 1)

window.close()
Resimi yakalamaya uğraşıyorum. Hayır, ne zorum varsa, timeout=0 yerine timeout=10 yap yavaş ilerlesin di mi..





Reçete - Column (sütun) kullanımı


Mesela kısa elemanların soluna uzun bir eleman yerleştirmek istiyoruz. Aşağıdaki örnekte 3 satır yüksekliğindeki bir listbox elemanı 3 tane tek satırlık text ya da input elemanının soluna yerleştiriliyor. bu 3 tek saıtırlık eleman bir Column elemanı içinde toplanır. Column elemanının belli olabilmesi için de arkaplan rengi maviye boyanmıştır. Column içindeki her eleman arkaplanda mavi renge sahip olmalıdır.


ColumnUse.py
import PySimpleGUI as sg

sg.theme("BlueMono")

col = [
    [sg.Text("col Satır 1", text_color="white", background_color="blue")],
    [sg.Text("col Satır 2", text_color="white", background_color="blue"), sg.Input("col Input 1")],
    [sg.Text("col Satır 3", text_color="white", background_color="blue"), sg.Input("col Input 3")]
]

layout = [
    [sg.Listbox(values=("Listbox item 1", "Listbox item 2", "Listbox item 3"), 
        select_mode=sg.LISTBOX_SELECT_MODE_MULTIPLE, size=(20, 3)),
        sg.Column(col, background_color="blue")],
    [sg.Input("Son input")],
    [sg.OK()]
]

event, values = sg.Window("Column içeren pencere", layout).read()

sg.popup(event, values, line_width=200)




Reçete - Text elemanı update - kalıcı pencere


Bu basit uygulama penceresi sürekli açık kalıyor, işlem yapıyor ve sonucunu yazıyor. X butonu tıklanınca kapanıyor.


TextUpdate.py
import PySimpleGUI as sg

layout = [
    [sg.Txt("Hesaplamak için değerleri giriniz")],
    [sg.In(size=(8, 1), key="-BÖLÜNEN-")],
    [sg.Txt("_"*10)],
    [sg.In(size=(8, 1), key="-BÖLEN-")],
    [sg.Txt("", size=(8, 1), key="-OUTPUT-")],
    [sg.Button("Hesapla", bind_return_key=True)]
]

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

while True:
    event, values = window.read()
    if event is not None:
        try:
            bölünen = float(values["-BÖLÜNEN-"])
            bölen = float(values["-BÖLEN-"])
            hesap = bölünen / bölen
        except:
            hesap = "Geçersiz"
        window["-OUTPUT-"].update(hesap)
    else:
        break

window.close()



Reçete - Bir eleman diğerini günceller - Bileşik elemanlar



Bu reçete bir slider'a nasıl değer göstergesi eklenebileceğine bir örnek.

Compound.py
import PySimpleGUI as sg

layout = [
    [sg.Text("Slider demosu"), sg.Output(size=(30, 3))],
    [sg.T("0", key="-LEFT-", size=(3, 1)), 
     sg.Slider((1, 100), key="-SLIDER-", size=(30, 20), orientation="h", enable_events=True, disable_number_display=True),
     sg.T("0", key="-RIGHT-", size=(3, 1))],
    [sg.Button("Göster"), sg.Exit()]
]

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

while True:
    event, values = window.read()
    if event in (None, "Exit"):
        break
    if event == "Göster":
        print(event, values)
    window["-LEFT-"].update(values["-SLIDER-"])
    window["-RIGHT-"].update(values["-SLIDER-"])

window.close()



Reçete - Birden çok pencere


Bu reçete çoklu pencereler için bir paterni gösteriyor. İkinci pencereyi gösterirken birinci pencere aktif olmuyor. Etkileşimin devam etmesini engellemek için birinci pencere gizleniyor.


MultipleWindow.py
import PySimpleGUI as sg

layout = [
    [sg.Text("Pencere 1")],
    [sg.Input()],
    [sg.Text("", key="_OUTPUT_", size=(40, 1))],
    [sg.Button("2ye geç")]
]

win1 = sg.Window("Pencere 1", layout)
win2_active = False

while True:
    ev1, vals1 = win1.read(timeout=100)
    if ev1 is None:
        break
    win1["_OUTPUT_"].update(vals1[0])

    if ev1 == "2ye geç" and not win2_active:
        win2_active = True
        win1.hide()
        layout2 = [[sg.Text("Pencere 2")], [sg.Exit()]]
        win2 = sg.Window("Pencere 2", layout2)

        while True:
            ev2, vals2 = win2.read()
            if ev2 in (None, "Exit"):
                win2.close()
                win2_active = False
                win1.UnHide()
                break

win1.close()





Reçete - tkinter Canvas elemanı


Canvas (Tuval) elemanı direk ulaşılabilen birkaç tkinter nesnesinden biridir. tkinter Canvas elemanı PySimpleGUI Canvas elemanından şöyle ulaşılabilir.

    can = sg.Canvas(size=(100,100))      
    tkcanvas = can.TKCanvas      
    tkcanvas.create_oval(50, 50, 100, 100)  

Canvas elemanı üzerinde karalamak eğlenceli olsa da Graph elemanı kullanmak çok daha rahat olacaktır. Tkinter koordinat sistemi hakkında endişelenmeden kendi koordinat sisteminizde çalışabilirsiniz.


Canvas.py
import PySimpleGUI as sg

layout = [
    [sg.Canvas(size=(100, 100), background_color="red", key="canvas")],
    [sg.T("Daire rengini değiştirin :"), sg.Button("Kırmızı"), sg.Button("Mavi")]
]

window = sg.Window("Canvas test", layout)
window.Finalize()

canvas = window["canvas"]
cir = canvas.TKCanvas.create_oval(50, 50, 100, 100)

while True:
    event, values = window.read()
    if event is None:
        break
    if event == "Mavi":
        canvas.TKCanvas.itemconfig(cir, fill="blue")
    elif event == "Kırmızı":
        canvas.TKCanvas.itemconfig(cir, fill="red")

window.close()





Reçete - Graph elemanı - daire, dikdörtgen vs çizmek


tkinter elemanını kullandığımız gibi Graph elemanı kullanarak da çizim yapabiliriz. Graph elemanı programcıya kendi koordinat sistemini kullanmak gibi avantajlar sağlar. 


Graph.py
import PySimpleGUI as sg

layout = [
    [sg.Graph(canvas_size=(400, 400), graph_bottom_left=(0, 0), graph_top_right=(400, 400), background_color="red", key="graph")],
    [sg.T("Daire rengini değiştirin:"), sg.Button("Kırmızı"), sg.Button("Mavi"), sg.Button("Kaydır")]
]

window = sg.Window("Graph test", layout)
window.Finalize()

graph = window["graph"]
circle = graph.DrawCircle((75, 75), 25, fill_color="black", line_color="white")
point = graph.DrawPoint((75, 75), 10, color="green")
oval = graph.DrawOval((25, 300), (100, 280), fill_color="purple", line_color="purple")
rectangle = graph.DrawRectangle((25, 300), (100, 280), line_color="purple")
line = graph.DrawLine((0, 0), (100, 100))

while True:
    event, values = window.read()
    if event is None:
        break
    if event == "Mavi":
        graph.TKCanvas.itemconfig(circle, fill="blue")
    elif event == "Kırmızı":
        graph.TKCanvas.itemconfig(circle, fill="red")
    elif event == "Kaydır":
        graph.MoveFigure(point, 10, 10)
        graph.MoveFigure(circle, 10, 10)
        graph.MoveFigure(oval, 10, 10)
        graph.MoveFigure(rectangle, 10, 10)

window.close()





Reçete - Dokunmatik ekran tuşu


Bu uygulama Raspberry Pi'de kullanılmış bir uygulamanın dokunmatik ekran arabirimi. Biliyor musunuz Raspberry Pi ve PySimpleGUIWeb kütüphanesi kullanarak çok etkili ev otomasyon uygulamaları kolayca yapılabilir. Cep telefonumuz üzerinden vedeki cihazları kontrol edebiliriz. 

Rakamlar butonlar ile girildiği için üstteki input elemanının içeriği butonlara tıklandıkça güncelleniyor. Bu reçetede bazı özellikler kullanılmış.
  • Default eleman boyutu
  • auto_size_buttons parametresi
  • Pencere elemanlarının içerik güncellenmesi (Text, Input)

TouchKeypad.py
import PySimpleGUI as sg

layout = [
    [sg.Text("Şifrenizi giriniz")],
    [sg.Input(size=(10, 1), justification="right", key="input")],
    [sg.Button("1"), sg.Button("2"), sg.Button("3")],
    [sg.Button("4"), sg.Button("5"), sg.Button("6")],
    [sg.Button("7"), sg.Button("8"), sg.Button("9")],
    [sg.Button("Gönder"), sg.Button("0"), sg.Button("Sil")],
    [sg.Text(size=(15, 1), font=("Helvetica", 18), text_color="red", key="out")]
]

window = sg.Window("Keyboard", layout, default_button_element_size=(5, 2), auto_size_buttons=False)

keys_entered = ""

while True:
    event, values = window.read()
    if event is None:
        break
    if event == "Sil":
        keys_entered = ""
    elif event in "1234567890":
        keys_entered = values["input"]
        keys_entered += event
    elif event == "Gönder":
        keys_entered = values["input"]
        window["out"].update(keys_entered)

    window["input"].update(keys_entered)

window.close()





Reçete - Matplotlib penceresini GUI penceresi ile kullanmak


PySimpleGUI'de Matplotlib kullanmanın 2 yöntemi var. İkisi de tkinter temelli matplotlib kullanır. Basit olani Matplotlib ve PySimpleGUI pencerelerinin aynı anda çalışması. 

Matplotlib kütüphanesini eklemek için konsolda
pip install matplotlib

İlk önce PySimpleGUI penceresi açılır ve bize 3 opsiyon sunar.


Plot butonuna tıkladığımızda Matplotlib penceresi açılır.


Matplotlib penceresi açıkken "Popup" butonuna tıkladığımızda GUI penceremizin hala aktif olduğunu görürüz.

Matplotlib.py
import PySimpleGUI as sg
import matplotlib.pyplot as plt

def draw_plot():
    plt.plot([0.1, 0.2, 0.5, 0.7])
    plt.show(block=False)

layout = [[sg.Button("Plot"), sg.Cancel(), sg.Button("Popup")]]

window = sg.Window("Matplotlib kullanımı", layout)

while True:
    event, values = window.read()
    if event in (None, "Cancel"):
        break
    elif event == "Plot":
        draw_plot()
    elif event == "Popup":
        sg.popup("Uygulamanız hala çalışıyor")

window.close()





Reçete - Matplotlib grafiğini pencere içinde göstermek


Canvas elemanı kullanarak GUI penceremizde matplotlib grafiğni gösterebiliriz.


Matplotlib2.py
import PySimpleGUI as sg
from tkinter import *
from random import randint
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, FigureCanvasAgg
from matplotlib.figure import Figure
import matplotlib.backends.backend_tkagg as tkagg
import tkinter as Tk

fig =Figure()

ax = fig.add_subplot(111)
ax.set_xlabel("X ekseni")
ax.set_ylabel("Y ekseni")
ax.grid()

def draw_figure(canvas, figure):
    figure_canvas_agg = FigureCanvasTkAgg(figure, canvas)
    figure_canvas_agg.draw()
    figure_canvas_agg.get_tk_widget().pack(side='top', fill='both', expand=1)
    return figure_canvas_agg

layout = [
    [sg.Text("Matplotlib Animasyon", size=(40, 1), justification="center", font=("Helvetica", 20))],
    [sg.Canvas(size=(640, 480), key="canvas")],
    [sg.Exit(size=(10, 2), pad=((280, 0), 3), font=("Helvetica", 14))]
]

window = sg.Window("Matplotlib grafiğin PySimpleGUI penceresine eklenmesi", layout)
window.Finalize()

canvas_elem = window["canvas"]

graph = FigureCanvasTkAgg(fig, master=canvas_elem.TKCanvas)

dpts = [randint(0, 10) for x in range(101)]
figure_canvas_agg = draw_figure(window["canvas"].TKCanvas, fig)

for i in range(len(dpts)):
    event, values = window.read(timeout=20)
    if event in (None, "Cancel"):
        exit(69)

    ax.cla()
    ax.grid()

    ax.plot(range(20), dpts[i: i+20], color="purple")
    graph.draw()

    figure_canvas_agg.draw()


window.close()


Kodun ayrıntısına girmek isterdim ama hem Tkinter hem Matplotlib bana göre çok karmaşık, zaten yukarıdaki kodu da zor çalıştırdım.





Reçete - Buton durumları ve sıkı bir yerleşim


Bu örnek yerleşim Tkinter'den bir uyarlama, güzel bir yerleşimi ve görüntüsü var. Bu reçete ayrıca daha sonra örnek alabileceğimiz buton etkileşimleri de içeriyor. 

Diğer GUI kütüphanelerinde bu uygulama görev foonksiyonlarının buton olaylarına bağlanması şeklinde çalışacaktı. Olay döngüsü yönetici buton etkileşimlerinde karşı gelen görev fonksiyonu varsa onu çağıracaktı. Bu aşağıdaki örnekte ise buton etkileşimleri sadece üzerlerindeki yazılar ile algılanıp hepsi aynı yerde işlenip bitiriliyor.


TightLayout.py
import PySimpleGUI as sg

sg.theme("Dark")
sg.SetOptions(element_padding=(0,0))

layout = [
    [sg.T("Kullanıcı:", pad=((3, 0), 0)), sg.OptionMenu(values=("User 1", "User 2"), size=(20, 1)), sg.T("0", size=(8, 1))],
    [sg.T("Müşteri:", pad=((3, 0), 0)), sg.OptionMenu(values=("Müşteri 1", "Müşteri 2"), size=(20, 1)), sg.T("1", size=(8, 1))],
    [sg.T("Notlar", pad=((3, 0), 0)), sg.In(size=(44, 1), background_color="white", text_color="black")],
    [sg.Button("Start", button_color=("white", "black"), key="Start"),
     sg.Button("Stop", button_color=("white", "black"), key="Stop"),
     sg.Button("Reset", button_color=("white", "firebrick3"), key="Reset"),
     sg.Button("Submit", button_color=("white", "springgreen4"), key="Submit")]
]

window = sg.Window("Zaman Kaydedici", layout, default_element_size=(12, 1), default_button_element_size=(12, 1),
                    auto_size_text=False, auto_size_buttons=False, text_justification="r")
window.Finalize()
window["Stop"].update(disabled=True)
window["Reset"].update(disabled=True)
window["Submit"].update(disabled=True)

recording = have_data = False

while True:
    event, values = window.read()
    print(event)
    if event is None:
        exit(69)
    if event == "Start":
        window["Start"].update(disabled=True)
        window["Stop"].update(disabled=False)
        window["Reset"].update(disabled=False)
        window["Submit"].update(disabled=True)
        recording = True
    elif event == "Stop" and recording:
        window["Start"].update(disabled=False)
        window["Stop"].update(disabled=True)
        window["Submit"].update(disabled=False)
        recording = False
        have_data = True
    elif event == "Reset":
        window["Start"].update(disabled=False)
        window["Stop"].update(disabled=True)
        window["Submit"].update(disabled=True)
        window["Reset"].update(disabled=False)
        recording = False
        have_data = False
    elif event == "Submit" and have_data:
        window["Start"].update(disabled=False)
        window["Stop"].update(disabled=True)
        window["Submit"].update(disabled=True)
        window["Reset"].update(disabled=False)
        recording = False




Reçete - Scriptler için şifre koruması


Bir programda 2 script yazıyoruz. Üstteki yarısında hash kodunu oluşturuyoruz. Sonra onu aşağıdaki kodun içine yapıştırıyoruz. Alttaki kısımı programlarımız içine kopyalayıp, kaynak kodunun içine şifreyi yazmadan programımızı şifreleyebiliriz. 



Password.py
import PySimpleGUI as sg
import hashlib

"""
    Scriptiniz için şifreli girişi kodun içine şifreyi koymadan sağlayın
    Verilen GUI ile scriptiniz için bir SHA1 hash kodu oluşturun.
    Programınızdaki değişkene bunu yapıştırarak karumayı gerçekleştirin
    1. Şifrenize karar verin
    2. Programı çalıştırıp şifreye "gui" girerek seçtiğniz şifreye karşı gelen hash kodu oluşturun
    3. login_password_hash değişkenine bu hash kod değerini kopyalayıp yapıştırın
    4. Programı tekrar çalıştırıp yeni şifrenizle girişi test edin
"""

# Şifrenize ait hash kodu üretmek için bu GUI'yi kullanın
def HashGeneratorGUI():
    layout = [
        [sg.T("Şifre Hash Üreteci", size=(30, 1), font=("Any", 15), justification="center")],
        [sg.T("Şifre"), sg.In(key="password")],
        [sg.T("SHA Hash"), sg.In("", size=(40, 1), key="hash")]
    ]

    window = sg.Window("SHA Üreteci", layout, auto_size_text=False, default_element_size=(10, 1),
                    text_justification="r", return_keyboard_events=True, grab_anywhere=False)

    while True:
        event, values = window.read()
        if event is None:
            exit(69)

        password = values["password"]
        try:
            password_utf = password.encode("utf-8")
            sha1hash = hashlib.sha1()
            sha1hash.update(password_utf)
            password_hash = sha1hash.hexdigest()
            window["hash"].update(password_hash)
        except:
            pass


# ------------------------- Bu kodu programınıza kopyalayın ------------------------- #
# SHA1 hash kodlarını karşılaştırarak şifrenizi kontrol eder
def PasswordMatches(password, hash):
    password_utf = password.encode("utf-8")
    sha1hash = hashlib.sha1()
    sha1hash.update(password_utf)
    password_hash = sha1hash.hexdigest()
    if password_hash == hash:
        return True
    else:
        return False
    
login_password_hash = '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8'
password = sg.popup_get_text("Şifre", password_char="*")
if password == "gui":            # kendi programınıza kopyalarken bu satırı silin
    HashGeneratorGUI()          # kendi programınıza kopyalarken bu satırı silin
    exit(69)                    # kendi programınıza kopyalarken bu satırı silin
if PasswordMatches(password, login_password_hash):
    print("Giriş başarılı")
else:
    print("Giriş geçersiz")

Ben bu kodu çok sevdim. Yeni bir şey öğrendim. Şimdi burada üretilen hash kodu test için bir program yazalım.

PasswordTest.py
import PySimpleGUI as sg
import hashlib

# SHA1 hash kodlarını karşılaştırarak şifrenizi kontrol eder
def PasswordMatches(password, hash):
    password_utf = password.encode("utf-8")
    sha1hash = hashlib.sha1()
    sha1hash.update(password_utf)
    password_hash = sha1hash.hexdigest()
    if password_hash == hash:
        return True
    else:
        return False
    
login_password_hash = '7110eda4d09e062aa5e4a390b0a572ac0d2c0220'
password = sg.popup_get_text("Şifre", password_char="*")
if PasswordMatches(password, login_password_hash):
    print("Giriş başarılı")
else:
    print("Giriş geçersiz")

Bu program gördüğümüz gibi yukarıdaki programda kopyalamamız belirtilen kısım. sadece login_password_hash değişkenine yukarıdaki programla ürettiğmiz hash kodunu kopyalayıp yapıştırıyoruz. Örnekte "1234" şifresine karşı gelen hash kod var. Yani bu test programını kopyalayıp yapıştırırsanız şifreniz "1234" olursa işlem başarılı olacaktır.





Reçete - Masaüstünde serbest toolbar



FloatingToolbar.py
import PySimpleGUI as sg
import os

ROOT_PATH = "./"

def Launcher():

    def print(line):
        window["output"].update(line)


    sg.theme("Dark")

    namesonly = [f for f in os.listdir(ROOT_PATH) if f.endswith(".py")]

    sg.SetOptions(element_padding=(0, 0), button_element_size=(12, 1), auto_size_buttons=False)

    layout = [
        [sg.Combo(values=namesonly, size=(35, 30), key="demofile"),
         sg.Button("Çalıştır", button_color=("white", "#001688")),
         sg.Button("Program 1"), sg.Button("Program 2"),
         sg.Button("Program 3", button_color=("white", "#350088")),
         sg.Button("Çıkış", button_color=("white", "firebrick3"))],
        [sg.T("", text_color="white", size=(50, 1), key="output")]
    ]

    window = sg.Window("Serbest Toolbar", layout, keep_on_top=True, no_titlebar=True, grab_anywhere=True)

    while True:
        event, values = window.read()
        if event in (None, "Çıkış"):
            break
        if event == "Program 1":
            print("Program 1 inizi burada çalıştırın")
        elif event == "Program 2":
            print("Program 2 nizi burada çalıştırın")
        elif event == "Çalıştır":
            file = values["demofile"]
            print("Çalıştırılıyor -> %s"%file)
            os.system("python " + os.path.join(ROOT_PATH, file))
        else:
            print(event)

    window.close()





if __name__ == "__main__":
    Launcher()





Reçete - Masaüstü serbest widget - Zamanlayıcı


Bu küçük pencereyi masaüstünüzde çalışır vaziyette bırakabilirsiniz. Buna benzer şeyler görmüşsünüzdür, emailleri kontrol eden, server pingleri takip eden, sistem bilgilerini gösteren vs.

Kodun büyük kısmı butonların görevlerini işlemekten ibaret. Sanırım PySimpleGUI'de işlerin ne kadar kolay yapıldığını gördükçe aklınızdan bir sürü yeni uygulama fikri geçiyordur. 


FloatingTimer.py
import PySimpleGUI as sg
import time

sg.theme("Black")
sg.SetOptions(element_padding=(0,0))

layout = [
    [sg.Text("")],
    [sg.Text("", size=(8, 2), font=("Helvetica", 20), justification="center", key="text")],
    [sg.Button("Pause", key="button", button_color=("white", "#001480")),
     sg.Button("Reset", button_color=("white", "#007339"), key="Reset"),
     sg.Exit(button_color=("white", "firebrick4"), key="Exit")]
]

window = sg.Window("Zaman İzler", layout, no_titlebar=True, auto_size_buttons=False, keep_on_top=True, grab_anywhere=True)

# --------------- ana döngü ---------------
current_time = 0
paused = False
start_time = int(round(time.time() * 100))

while True:
    if not paused:
        event, values = window.read(timeout=10)
        current_time = int(round(time.time() * 100)) - start_time
    else:
        event, values = window.read()
    if event == "button":
        event = window[event].GetText()
    
    # ---------- buton görevleri ----------
    if event == "Exit" or event is None:
        break
    if event == "Reset":
        start_time = int(round(time.time() * 100))
        current_time = 0
        paused_time = start_time
    elif event == "Pause":
        paused = True
        paused_time = int(round(time.time() * 100))
        element = window["button"]
        element.update(text="Run")
    elif event == "Run":
        paused = False
        start_time = start_time + int(round(time.time() * 100)) - paused_time
        element = window["button"]
        element.update(text="Pause")
    
    # ---------- zamanlayıcıyı pencerede göster ----------
    window["text"].update("{:02d}:{:02d}:{:02d}".format((current_time // 100) // 60,
                                                        (current_time // 100) % 60,
                                                        current_time % 100))

window.close()

Aynı butonun yazısını değiştirerek 2 değişik görevde kullanmamız bu kodun ilginç yanı.





Reçete - Masaüstü serbest widget - CPU kullanımı


Yukarıdaki zamanlayıcı dımbırtısı gibi, bu uygulama da çalışmasını sürekli devam ettiriyor. Bu uygulamayaı çalıştırabilmemiz için psutil paketini yüklemiş olmamız gerekir. 

Spinner kaç saniyede bir okuma yapılacağını ayarlar. 


FloatingUtilization.py
import PySimpleGUI as sg
import psutil

sg.theme("Black")
layout = [
    [sg.Text("")],
    [sg.Text("", size=(10, 1), font=("Helvetica", 20), justification="center", key="text")],
    [sg.Exit(button_color=("white", "firebrick4"), pad=((15, 0), 0)),
     sg.Spin([x + 1 for x in range(10)], 1, key="spin")]
]

window = sg.Window("CPU Kullanımı", layout, no_titlebar=True, auto_size_buttons=False, 
                    keep_on_top=True, grab_anywhere=True)

while True:
    event, values = window.read(timeout=0)

    if event in (None, "Exit"):
        break
    try:
        interval = int(values["spin"])
    except:
        interval = 1

    cpu_percent = psutil.cpu_percent(interval=interval)

    window["text"].update(f"CPU %{cpu_percent}")

window.close()




Reçete - Menüler


Menüler aslında menü barda yerleştirilmiş butonlardan başka bir şey değildir. Bir menü elemanına tıkladığımızda elemana ait yazıyı değer alan bir buton olayı elde ederiz. Aynı üzerinde yazı bulunan bir buton gibi. 

Menüler pencere yerleşiminden farklı yerde tanımlanırlar. Sonra da pencereye sg.Menu(menu_layout) komutuyla eklenirler. Menü tanımlaması ana başlıklar ve altında alt menüler şeklinde liste olarak yapılır. Alt menüler ve onların da alt menülerini düşünürsek bu listelerden oluşan bir liste olarak karşımıza çıkacaktır. Aşağıdaki reçeteyi uygulayıp , kendi isteklerinize göre değiştirebilirsiniz. 


Menus.py
import PySimpleGUI as sg

sg.theme("LightGreen")
sg.SetOptions(element_padding=(0,0))

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

# ----- GUI tanımlaması ----- #
layout = [
    [sg.MenuBar(menu_def)],
    [sg.Output(size=(60 ,20))]
]

window = sg.Window("Windows-stili program", layout, default_element_size=(12, 1), auto_size_text=False,
                    auto_size_buttons=False, default_button_element_size=(12, 1))

# ----- menü seçimlerini işleyelim ----- #
while True:
    event, values = window.read()
    if event in (None, "Çıkış"):
        break
    print("Buton = ", event)

    if event == "Hakkında...":
        sg.popup("Bu program hakkında", "Versiyon 1.0", "PySimpleGUI çalışıyor...")
    elif event == "Aç":
        filename = sg.popup_get_file("Açılacak dosya", no_window=True)
        print(filename)

window.close()





Reçete - Graph elemanı ile grafik çizmek



Graph2.py
import math
import PySimpleGUI as sg

layout = [[sg.Graph(canvas_size=(400 ,400), graph_bottom_left=(-105, -105), 
                    graph_top_right=(105 ,105), background_color="white",
                    key="graph", tooltip="Çok güzel grafik")]]

window = sg.Window("Sinüs fonksiyonu grafiği", layout).Finalize()
graph=window["graph"]

graph.DrawLine((-100, 0), (100, 0))
graph.DrawLine((0, -100), (0, 100))

for x in range(-100, 101, 20):
    graph.DrawLine((x, -3), (x, 3))
    if x != 0:
        graph.DrawText(x, (x, -10), color="green")
for y in range(-100, 101, 20):
    graph.DrawLine((-3, y), (3, y))
    if y != 0:
        graph.DrawText(y, (-10, y), color="blue")

# ----- grafiğin çizimi ----- #
for x in range(-100, 100):
    y = math.sin(x/20)*50
    graph.DrawCircle((x, y), 2, line_color="red", fill_color="blue")

event, values = window.read()

DrawCircle yerine başka metodlar kullanarak değişik çizim elde edilebilir.





Reçete -Tab'lar


Tablar bize sadece karmaşık bir program kazandırmaz, aynı zamanda daha fazla eleman için yer de kazandırır. Tab 3 konteyner elemandan biridir (içine eleman eklenebilen elemanlar). Diğerlerinin biri Column diğeri de Frame. Diğer ikisini daha önce görmüştük.


Tabs.py
import PySimpleGUI as sg

tab1_layout = [[sg.T("Bu Tab-1 içinde")]]

tab2_layout = [[sg.T("Bu Tab-2 içinde")],
                [sg.In(key="in")]]

layout = [[sg.TabGroup([[sg.Tab("Tab-1", tab1_layout, tooltip="tip"), 
                         sg.Tab("Tab-2", tab2_layout)]], tooltip="tip2")],
            [sg.Button("Oku")]]

window = sg.Window("Tab test", layout, default_element_size=(12, 1))

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

window.close()

TabGroup içinde tabların ve gruptaki tüm tablarda geçerli olan butonun yerleşimdeki yerlerine dikkat edelim.




Reçete - Son - Windows .exe dosyası yapmak


Bu son reçetemizde Windows kullanıcıları için ".exe" uygulama dosyası yapacağız. Windows'ta .exe dosyası oluşturursak başka bilgisayarda uygulamamızı çalıştırmak için ona da Python kurmamıza gerek kalmaz. Bu amacımıza ulaşmak için PyInstaller paketinin yüklü olması gerekir. Konsolda

pip install PyInstaller

Bundan sonra Python scriptimizi .exe dosyaya çevirmek için yapacağımız işlem basit bir komut girmek. Mesela "Menus.py" dosyamızı .exe yapmak istersek

pyinstaller -wF Menus.py

"dist" klasörü oluşturacak ve içine "Menus.exe" dosyasını ekleyecektir. Bu programı Python olmadan direk olarak Windows'ta çalıştırabiliriz.

Eh 3 bölüm güzel ama uzun bir yazı oldu. Çok şey öğrendik, artık bu yazıyı okuyup ta Python'da da GUI programı yazmak çok zor diyen kalmaz herhalde. Benzer kolay arabirim oluşturan kütüphaneler olabilir ama Python'un da gücü eklenince GUI program yazmak artık çok daha kolay ve eğlenceli.

Tekrar görüşmek üzere, kalın sağlıcakla..

<< 2. Bölüm










Hiç yorum yok:

Yorum Gönder