<< 2. Bölüm
Merhaba. Devam edelim. Önceki iki bölümden sonra örnek GUI reçeteleri ile devam ediyoruz.
Matplotlib penceresi açıkken "Popup" butonuna tıkladığımızda GUI penceremizin hala aktif olduğunu görürüz.
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.
Ben bu kodu çok sevdim. Yeni bir şey öğrendim. Şimdi burada üretilen hash kodu test için bir program yazalım.
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.
Aynı butonun yazısını değiştirerek 2 değişik görevde kullanmamız bu kodun ilginç yanı.
DrawCircle yerine başka metodlar kullanarak değişik çizim elde edilebilir.
TabGroup içinde tabların ve gruptaki tüm tablarda geçerli olan butonun yerleşimdeki yerlerine dikkat edelim.
"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
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