Dün TkInter'da GUI'yi Ayrı Dosyaya Bölme başlığında bir örnek paylaşmıştım, kullanıcı login yaptıktan sonra toplevel
açılıyordu. Yapacağınız ufak değişiklikler ile toplevel
yerine login ekranının yok olmasını yerine yeni bir frame widgetinin gelmesini sağlayabilirsiniz.
Örnek:
Programın dosyalarının ağaç dizin yapısı şu şekilde:
.
├── run.py
└── Scripts
├── button.py
├── entry.py
├── frame.py
├── __init__.py
├── modules.py
└── utilities.py
Bunlar da dosyaların içinde yer alan kodlar:
Dosya: run.py
#!/usr/bin/python3.8
# -*- coding: utf-8 -*-
if __name__ == "__main__":
from Scripts import main
main()
Dosya: Scripts\modules.py
# -*- coding: utf-8 -*-
import tkinter as tk
from tkinter.messagebox import showwarning
Dosya: Scripts\__init__.py
# -*- coding: utf-8 -*-
from .modules import tk
from .button import Button
from .frame import LoginFrame
from .utilities import authenticate
def main():
root = tk.Tk()
login = LoginFrame(
master=root,
texts=["Username", "Password"],
max_chars=[20, 20]
)
apply_button = Button(
master=root,
text="\u2714",
color="green",
command=lambda: authenticate(*login.entries.values(), master=root)
)
root.mainloop()
Dosya: Scripts/button.py
# -*- coding: utf-8 -*-
from .modules import tk
class Button(tk.Button):
def __init__(self, color, *args, **kwargs):
super().__init__(*args, **kwargs)
self.configure(
activebackground=self["bg"],
activeforeground=color,
borderwidth=0,
highlightthickness=0,
font="Default 20",
fg=color
)
self.pack()
Dosya: Scripts\entry.py
# -*- coding: utf-8 -*-
from .modules import tk
class Entry(tk.Entry):
def __init__(self, max_char: int, *args, **kwargs):
super().__init__(*args, **kwargs)
self.bind(
sequence="<KeyRelease>",
func=lambda event: self.__apply_max_char(max_char=max_char)
)
self.configure(width=max_char)
if self._name == "password":
self.configure(show="*")
def __apply_max_char(self, max_char):
if len(self.get()) > max_char:
self.delete(max_char, "end")
Dosya: Scripts/frame.py
# -*- coding: utf-8 -*-
from .modules import tk
from .entry import Entry
class LoginFrame(tk.Frame):
def __init__(self, texts: list, max_chars: list, *args, **kwargs):
super().__init__(*args, **kwargs)
self.pack()
self.entries = self.__create_entries(
texts=texts,
max_chars=max_chars
)
def __create_entries(self, texts, max_chars):
entries = {}
for index, (text, max_char) in enumerate(zip(texts, max_chars)):
label = tk.Label(master=self, text=text)
label.grid(row=index, column=0, sticky="w")
entry = Entry(
master=self,
max_char=max_char,
name=text.lower()
)
entry.grid(row=index, column=1, sticky="w")
entries[text] = entry
return entries
class WelcomeFrame(tk.Frame):
def __init__(self, username: str, *args, **kwargs):
super().__init__(*args, **kwargs)
self.pack()
self.label = tk.Label(master=self, text=f"Welcome {username}")
self.label.pack()
Dosya: Scripts/utilities.py
# -*- coding: utf-8 -*-
from .modules import tk, showwarning
from .frame import WelcomeFrame
def get_entry_values(*entries):
return [ent.get() for ent in entries if isinstance(ent, tk.Entry)]
def has_authentication(*entries):
return get_entry_values(*entries) == ["Admin", "123456"]
def authenticate(*entries, master):
if has_authentication(*entries):
username = entries[0].get()
for child in master.winfo_children():
child.destroy()
WelcomeFrame(master=master, username=username)
else:
showwarning(
title="Warning",
message="Wrong username and password"
)
Mesela bakın burada __init__.py
dosyasında root
ile birlikte bir LoginFrame
ve bir Button
tanımlanıyor. Button
'un yapacağı işlem olan authenticate
ise utilities.py
dosyasında tanımlı. utilities.py
dosyasındaki authenticate
'e baktığımız zaman, bu fonksiyon LoginFrame
'e girilen kullanıcı adı ve şifresinin doğru olup olmamasına göre iki farklı işlem yapıyor. Şayet kullanıcı adı ve şifre doğruysa, LoginFrame
ve Button
yok ediliyor yerine WelcomeFrame
getiriliyor ya da ekrana bir uyarı penceresi getiriliyor.
Kodları bir inceleyin isterseniz.