Bu yazıda, bir şirketteki çalışanları yönetme kabiliyetimizi artırabilecek bir uygulama yazacağız. Bu uygulama sayesinde yetkili kişi giriş yapabilirse admin paneline ulaşabilecek ve o panel sayesinde yeni bir tablo oluşturma, tabloya çalışan ekleme, tablodan çalışan silme gibi daha önce gördüğümüz işlemleri yapabilecek.
Bu uygulamanın oldukça büyük eksiklikleri mevcuttur. Blogun sonunda "Geliştirme Önerileri" başlığı altında bunlara değinip gerisini size bırakacağım.
Şimdi, yapmamız gereken ilk şey bir giriş sayfası oluşturmak olmalıdır. Sonuçta yetkisi olmayan insanlar o panele erişmemeli. Bunun için admins.db isimli bir veri tabanı oluşturdum ve içerisine iki tane admin ekledim.

Oldukça hızlı ve basit bir şekilde oluşturdum. Geliştirme önerileri kısmında bu noktada neler yapabileceğinizi anlatacağım. administrators isimli bir tablo içerisinde yalnızca username ve password isimli iki sütun açtım ve değerlerini girdim. Biri admin1, diğeri admin2 olmak üzere iki adet adminimiz mevcut.
Şimdi, login.py isimli bir dosya açıyorum ve bir giriş yapma sayfası tasarlamaya başlıyorum.
İhtiyacımız olan üç şey var. Bunlardan biri tkniter, diğeri sqlite3, bir diğeri ise tkinter içerisinde bulunan messagebox. Bunları import ediyorum:

Şimdi, bir arayüz oluşturmamız lazım. Bunun için root isminde bir obje oluşturup ona özelliklerini veriyorum.

Şimdi, basitçe bir Welcome yazısı yazdıralım ve adminimize 'hoş geldin' diyelim. Bunun için bir Label oluşturuyorum.

Gördüğünüz üzere bir Label oluşturup onu root'un içine gömdüm. Sonrasında pady= değeri belirleyerek yazının konumunu belirledim ve .pack() diyerek bunun paketlenip arayüzde gözükmesini sağladım. Bunları zaten biliyorsunuz. Eğer kodunuz uzun olduysa ve bundan hoşlanmadıysanız ya da benim gibi ekran görüntüsü alacak yer ayırmak istiyorsanız kırmızı ok ile gösterdiğim şekilde bir ters slash koyup alt satıra inebilirsiniz. Aynı zamanda Label içerisindeki yazının kalın olmasını isterseniz daha önce gördüğümüz font= ifadesine 'bold' değerini verebilirsiniz.
Şimdi, bizim iki adet Label ve iki adet Entry nesnesine ihtiyacımız var. Bu alanlara kullanıcı adı (username) ve parola (password) girilecek. Bu yüzden bu nesneleri oluşturuyorum.

Dikkat edelim. Oluşturduğum Label ve Entry nesnelerinin isimlerini oldukça belirleyici bir şekilde yazdım. Örneğin usernameLabel ya da passwordEntry. Bu, oldukça önemlidir çünkü hangi nesnenin hangi satırda olduğunu bilmeniz, bilmeseniz bile anlamanız gerekir.
Sonrasında genel anlamda bu 4 nesnenin yerlerini place() fonksiyonu ile belirledim. En altta bulunan passwordEntry kısmına bakarsanız altı yeşil çizgi ile çizili bir yapı görürsünüz. Bunu daha önce görmedik. Eğer bir Entry alanına show='*' şeklinde bir ifade verirseniz o alana girilecek olan yazılar yıldız işareti ile sansürlenir. Elbette, yıldız işareti yerine başka bir şey de koyabilirsiniz, size kalmış. Hemen nasıl göründüğüne bakalım.

Şimdi, bir butona ihtiyacımız var. Ancak, onu koymadan önce bu butona tıklandığında ne olacağını belirlememiz lazım. Adminimiz, bu butona bastığında sistem ona giriş yetkisi verecek ya da vermeyecektir. Bizim zaten adminlerin kayıtlı olduğu bir veri tabanımız mevcuttu. O zaman giriş esnasında giriş yetkisi, veri tabanında yer alan password ile karşılaştırılarak yapılmalıdır, öyle değil mi? Eğer adminin girdiği kullanıcı adı ve parola, veri tabanındaki username ve password alanlarıyla eşleşiyorsa giriş izni verilecektir. Bunun için ilk önce fonksiyonun dışına, bir veri tabanı bağlantısı gerçekleştirmemiz gerekiyor.

İlk önce admins.db isimli veri tabanına bağlandım. Sonrasında bir cursor yani imleç oluşturdum. Sonrasında, butona tıklandığında ne olacağını belirleyeceğimiz, loginButton() isimli bir fonksiyon oluşturdum. Şu an ortada bir buton söz konusu değil; önce fonksiyonu yazalım.
İlk önce, veri tabanındaki kişilerin hepsini almamız yani görüntülememiz lazım ki girilen kullanıcı adını karşılaştırabilelim.

İmleç ve execute() fonksiyonu sayesinde admins.db veri tabanındaki administrators tablosunda bulunan username değerlerini sorguladım (SELECT username FROM administrators). Bu sorguyu yaptıktan sonra fetchall() diyerek bunları aldım. Hatırlarsanız fetchall() fonksiyonu, döndürdüğü değerleri bir liste içerisinde, birer Tuple olarak tutuyordu; zaten sağ taraftaki terminalden bunu görebiliyorsunuz. Ben, bu değerleri index mantığıyla değil, direkt olarak string değerler ile işlemek istiyorum. Dolayısıyla fetchall() fonksiyonunun döndürdüğü değerleri results isimli bir değişkene atıyorum ve şimdi bunları bir for döngüsü ile ayıklayacağım.

for result in results diyerek results listesinin içindeki elemanları kontrol edebiliyorum. Sonrasında bunları print() ettirdim ve sağ tarafta gördüğünüz üzere bunlar ayıklandı. Ancak, bu yeterli değil. Bizim, sade bir şekilde kullanıcı adına ulaşmamız lazım. Yani yanında virgül veya parantez olmamalı. Bunun için bir for döngüsü daha yazıp iç içe for yapısını kuruyorum.

İşte, amacıma ulaştım. Şu an, veri tabanındaki bütün adminlerin kullanıcı adları sade bir biçimde önüme düşüyor. Şimdi, kullanıcının usernameEntry alanına girdiği girdiyi ikinci for döngüsünde bulunan selected değişkeni ile karşılaştırmamız lazım.

if usernameEntry.get() in selected: koşulu ile adminimizin o Entry alanına girdiği değeri alıyor ve selected içerisindeki değerler ile karşılaştırıyoruz. Hatırlarsanız Entry içerisine girilen veriyi almak için get() kullanıyorduk.
Bu koşulun sağlanması durumunda yani eğer adminimiz, veri tabanında olan bir kullanıcı girdiyse o kullanıcı adına denk gelen parolayı çekiyoruz. SELECT password FROM administrators WHERE username='{selected}' komutu, adminin Cyber kullanıcı adını girmesi durumunda şuna dönüşecektir:
SELECT password FROM administrators WHERE username='Cyber'
Bu durumda, Cyber kullanıcı adına sahip olan satırdaki password değeri alınacaktır. Son olarak fetchall() diyorum ve bunu da passwd isimli bir değişkene atıyorum.

Amacımıza kısmen ulaştık. Parolaları alabildik ama dikkat ederseniz bunlar da birer liste içerisinde, birer Tuple'da barındırılıyor. O zaman bir ayıklama işlemi gerçekleştirelim.

[('...')] böyle bir yapıda o Tuple yani bir liste içerisindeki tek bir Tuple, sıfırıncı index değil midir? Elbette, öyledir. O zaman passwd[0] dersek o Tuple yapısına erişebiliriz, öyle değil mi? Kesinlikle. Gördüğünüz üzere, Tuple yapılarını aldık. Ancak, sorunumuz çözülmedi. Peki, Tuple yapılarında da index mantığı varsa ve o Tuple sadece bir elemandan oluşuyorsa o eleman sıfırıncı index olmaz mı? Bakalım.

Bu noktada passwd[0][0] şeklinde bir yapı görüyorsunuz ve bu yapı sorunumuzu çözdü. İlk [0] ifadesi, listenin sıfırıncı index'ini ifade ederken ikinci [0] ifadesi, Tuple'ın sıfırıncı index'ini ifade eder. O zaman passwd[0][0] ifadesini daha sonra da kullanabiliriz. Devam edelim.
Şimdi, adminimizin girdiği parolayı karşılaştırmamız lazım. Bunun için hem passwordEntry.get() hem de passwd[0][0] ifadesini kullanacağız.

if passwordEntry.get() == passwd[0][0] yani eğer kullanıcının girdiği parola değeri passwd[0][0] değerine eşitse... şeklinde bir koşul belirttik ve bu koşulun gerçekleşmesi durumunda "Successfully logged in" şeklinde bir mesaj verdik. Gerçekleşmemesi durumunda ise "Username or password is wrong" şeklinde bir mesaj verdik.
Peki, bu if-else bloklarında Python, passwordEntry.get() ve passwd[0][0] değerlerini nasıl karşılaştıracak? Yani passwordEntry.get() değerinin, hangi kullanıcının passwd[0][0] değerine ait olduğunu nereden bilecek? Dikkat ederseniz kurduğumuz yapı, iç içe bir yapı. Yani aslında her adımın gerçekleşmesi, bir koşula bağlı. Bu noktada if usernameEntry.get() in selected yapısı ile zaten kullanıcının girdiği kullanıcı adını kontrol ettik ve onu sakladık. if passwordEntry.get() ... bloğu ise, diğerinin içerisinde olduğu için bu blok, ona göre hareket edecektir.
Şimdi, butonumuzu tasarlayalım.

Butonu tasarlayıp command=loginButton diyerek loginButton() isimli fonksiyonu butonun içine gömdüm.
Şimdi, kodu çalıştıralım ve ne olacağını görelim. Ancak, aklınızda olsun; admin1 ve admin2 olarak iki adminimiz var ve bunların parolaları admin1-pwd, admin2-pwd şeklinde.

Bir şey girmedim ve yanlış dedi. Doğrusunu girelim.

Başarılı olduk. Bir de show='*' ifadesini kaldırıp öyle deneyelim.

Evet, giriş yapma sayfamız başarılı bir şekilde sonlandı. Son olarak veri tabanı bağlantısını sonlandıralım.

root.mainloop() ve connection.close() ifadelerini if __name__ == "__main__": içerisine taşıdım.
Şimdi, çalışanlara bakalım. Çalışan yaratalım, silelim, güncelleyelim.
Bunun için employee.db isminde bir veri tabanı ve employee.py isminde bir dosya açıyorum. Hemen sonrasında employee.py dosyasına gerekli modülleri aktarıyorum.

Şimdi, bir arayüz oluşturmamız lazım ama bunu büyük ekranda yapmamız lazım. Yapalım.

login.py dosyası root olduğu için buradaki arayüzü system olarak adlandırdım. Ekran büyüklüğünü 1920x1080 olarak ayarladım ve tam ekran oldu. Bu noktada dilerseniz şöyle bir şey yapabilirsiniz; yeni bir şey öğrenelim:

Ancak, bunu yaparsanız ekran tam anlamıyla kaplanır. Şöyle göstereyim:

Çıkmak için Alt+TAB tuşlarını kullanarak başka bir uygulamaya geçip programı el ile sonlandırmanız gerekir. (önce Alt'a basılı kalın, sonra TAB'a basın).
Bu kısımda birçok kod tekrarı göreceksiniz. Ancak, bunları el alışkanlığı kazanmanızı istediğim için uzun uzun yaptım. Devam edelim.
Şimdi, bir Label ile bir başlık oluşturalım.

Ekran boyutu 1920x1080 olduğu için fazladan ekran görüntüsü alıp arayüzü size göstereceğim. Bu Label, şunu yaratmış oldu.

Bu şekilde bir başlık oluşturduk. Blogun başında da söz ettiğim üzere daha önce gördüklerimizi yapacağız. Bu yüzden ilk önce tablo oluşturma ile alakalı bir şeyler yapalım.
Ancak, birden fazla farklı işlem olduğu için her işlemi birer LabelFrame içerisine koyarak çerçeveleyelim.

Bir LabelFrame oluşturdum ve içerisine Label(system) dedim; tablo oluşturma ile alakalı şeyleri bu çerçeve içine koyacağım. Bu noktada dikkat edelim; createTableFrame şeklinde bir değişken ismi tanımladım. Daha önce de söylediğim gibi, özellikle çok satırlı kodlarda değişken isimleri oldukça tanımlayıcı olmalıdır.
Şimdi, neye ihtiyacımız olduğunu belirleyelim. Tablo oluşturmak için ilk önce bir veri tabanına ihtiyacımız var. Sonrasında kullanıcıdan bir tablo ismi ve değişken değerleri almamız gerekiyor. Hatırlayalım; tablo şu şekilde oluşturuluyordu:
CREATE TABLE IF NOT EXISTS <tablo ismi> (<değişken> <veri tipi>, ...)
O zaman bizim, 3 Label ve 3 Entry nesnesine ihtiyacımız var. Yapalım.

getDbNameEntryCREATE şeklinde bir değişken atadım ve karşılığında Entry(createTableFrame) dedim. Bu durumda bu Entry nesnesini az önceki LabelFrame yani çerçeve içerisine gömmüş olduk. Diğerleri de aynı mantıkta ilerliyor, değişen tek şey nesnelerin konumları ve yazılardır. Bu kodların sonucunda şöyle bir şeyle karşılaşmamız lazım:

Bence güzel oldu. Ancak, bizim bir de butona ihtiyacımız var. Hemen koyalım.

createTableButton isminde bir buton oluşturdum ve onu, Button(createTableFrame) diyerek çerçevenin içine koydum. Sonrasında zaten konumu, büyüklüğü size kalmış. Bu kod sonucunda şöyle bir görüntü bizi bekliyor olacak:

Başardık, ilk çerçevemiz hazır. Şimdi sıra, bu nesnelerin işlevli hâle gelmesini sağlamakta. Bunun için bir fonksiyon açıyorum.

createTableMethod() isminde bir fonksiyon açtım ve içerisine, biraz önce tanımladığımız Entry'lerin değerlerini alan bir kod yazdım. Şimdi, veri tabanına bağlanmamız gerekiyor.

Bağlanacağımız veri tabanı, kullanıcının DB Name: kısmına gireceği veri tabanı olacak. Dolayısıyla bunu bir fstring içerisinde yazmak daha mantıklı olacaktır. Eğer direkt olarak bağlanılacak veri tabanının ismini biliyor olsaydık connect("...") şeklinde yazardık.
Bağlantımız ve imlecimiz oluştuğuna göre bir SQL sorgusu yazabiliriz. Bunun için CREATE TABLE IF NOT EXISTS komutunu vereceğiz. Sonrasında olacakları görelim.

Yine fstring kullanarak ana komutumuzu yazdıktan sonra tableName ve variables değişkenlerini oraya yerleştirdik. Bu noktada kullanıcı tablo ismini ve değişkenleri girdiğinde şöyle bir yapı oluşacak:
CREATE TABLE IF NOT EXISTS TopManagers (name TEXT, age INT...)
Sonrasında commit() ve close() fonksiyonlarını çağırıp işlemin başarılı olması durumunda "Table is created successfully" şeklinde bir mesaj veriyoruz. Ancak, başarısız olması durumunda da bir mesaj verebilmek adına bu kodları try-except içerisine atabiliriz:

Evet, böyle daha sağlıklı oldu. Şimdi, biraz önce oluşturduğumuz butona bu fonksiyonu gömelim.

Evet, işlemlerimiz tamamlandı. Şimdi, kodu çalıştırmak için gerekli verileri girelim:

Veri tabanımızın ismi employee.db, oluşturmak istediğimiz tablonun adı TopManagers ve değişkenlerimiz (name TEXT, age INT) şeklinde. Butona bastığımda arka tarafta çalıştırılacak SQL sorgusu tam olarak şu şekilde olacaktır:
CREATE TABLE IF NOT EXISTS TopManagers (name TEXT, age INT)
Dilerseniz buna soy isim ve maaş bilgisi de ekleyelim; yeni bir şey göstereceğim.

Soy isim değeri gözükmüyor ama surname TEXT olarak ayarladım. Dikkat edelim; daha önce görmediğiniz bir şey var: salary REAL. salary değişkeni maaşı ifade ederken REAL veri tipi float veri tipini ifade eder. Eğer virgüllü bir değer girmek isterseniz değişken isminden sonra REAL anahtar kelimesini girmeniz gerekir.
Şimdi, tablomuzu oluşturalım.

Bildirim, işlemin olumlu sonuçlandığını belirtiyor. Bakalım, gerçekten de öyle mi?

Bir de tablo görünümüne bakalım.

Tablo oluşturma işlemimiz gerçekten de başarılı olmuş. Ancak, dikkat ederseniz 2 adet sorunumuz var.
Birincisi; kullanıcı SQL sorgusu yazmayı bilmiyor olabilir. Normal şartlarda bu tarz programları kullanmaları için şirket, çalışanlarına eğitim verir; vermelidir. Ancak her ne kadar eğitim almış olursanız olun bazen aklınızdan uçup gidebilir ve eksik ya da yanlış girdiğiniz bir veri işten kovulmanıza sebep olabilir. Bu yüzden özellikle değişkenleri girdiğimiz kısım için bir yardım butonu oluşturmamız gerekiyor. Yapalım bakalım.

helpButtonCreate ismini verdiğim bu butonda her şeyi biliyorsunuz. Fakat bizim, bir uyarı vermemiz lazım ve bu uyarıyı normal şartlarda bir fonksiyon içerisine tanımlıyoruz. Dikkatli bakarsanız bunun bir saçmalıktan ibaret olduğunu görebilirsiniz. Yeşil kutuya bakalım; command=help dediğimizi ve help() fonksiyonunun şuna benzediğini düşünün:
def help():
return messagebox.showinfo("Usage", "USAGE (<variable name> <data type>, ...) \
\nYou can take support from your manager.")
Ve bu kadar. İçeriği farklı bir help butonuna tekrar ihtiyaç duyduğumuzda farklı bir fonksiyon daha tanımlamamız, çünkü içeriğin başka olması gerekecek; saçmalık. Bu yüzden orada bir lambda ifadesi görüyorsunuz. Hatırlayacağınız üzere lambda; tek seferlik, geçici bir fonksiyondu. lambda : dedikten sonra gereken mesajı veriyorum. Başka bir yerde başka bir mesaj vereceğim zaman ayrı bir fonksiyon tanımlamak yerine direkt olarak lambda diyorum ve olay bitiyor.
İsterseniz bu help butonunun nasıl bir şey olduğunu görelim ve ikinci sorunumuza bakalım.

Gördüğünüz üzere butonumuz güzelce yerleşmiş ve lambda fonksiyonu sayesinde tıklandığında işini yapabiliyor.
İkinci sorunumuz şöyle; tablo oluşturmak için gereken veri tabanı ismini kullanıcıdan alacağız. Ancak, bir sürü çerçeve ve bir sürü veri tabanı isteyen alanımız olacağını biliyorsunuz. Elbette, tek bir veri tabanı ismi isteyen tek bir Entry oluşturup her şeyi onunla çözebilirsiniz ama ben, varsayılan bir değer atamayı göstereceğim. Çünkü program her çalıştığında o alanı doldurmak gerçekten sıkıcı olabilir. Bunun için şöyle bir yol izliyorum:

defaultDatabase = StringVar() ifadesiyle beraber defaultDatabase.set("<veri tabanı ismi>") diyorum ve olay bitiyor. Şimdi, yapmamız gereken tek şey, veri tabanı ismi isteyen Entry nesnesini bulup bu değişkeni oraya yerleştirmektir.

Bunu yaptığımızda artık varsayılan veri tabanı employee.db olacaktır. Programı çalıştırıp görelim:

İşte bu kadar. Son olarak; satır sayısı oldukça artacağı için hangi kısmın neye ait olduğunu belirtmemiz gerekiyor. Bunu yapmak hem kodumuzu okuyacak olan başka insanlara yardımcı olacaktır hem de bizim için hata ayıklama işlemleri daha kolay olacaktır. Çünkü birazdan göreceksiniz; butonlar, yazılar vesaire hep birbirine benzemeye başlayacak.

Yazdığımız kodları kapsayan kısmın başına ve sonuna bir belirteç koyuyorum. Yukarıda gördüğünüz, kodun başlangıcını ifade ederken aşağıda gördüğünüz kod, kodun bitiş noktasını ifade edecektir:

Tablo oluşturma işlemini bitirdik ve şu ana kadar her şey güzel çalışıyor.
Şimdi, tablo silme işlemini yazalım.

Bunun için ilk önce belirteçlerimi ekliyorum ve tablo silmek için nelere ihtiyacım olduğunu düşünüyorum. Veri silmeyi görmüştük ama tablo silmeyi daha önce size göstermemiştim. Şimdi, onu öğreneceğiz.
Tablo silerken şu komutu kullanıyoruz: DROP TABLE <tablo ismi>
Demek ki tablo silmek için bir veri tabanı ismine bir de tablo ismine ihtiyacımız var. Elbette bir de buton lazım. Bunları hazırlamaya başlayalım.

Şimdi, bir çerçeve oluşturuyorum ve adını dropTableFrame koyuyorum. Unutmuyoruz; tanımlayıcı olacaklar. Bunu dedikten sonra LabelFrame(system) diyerek bunu, system isimli arayüzün içine atıyorum. Sonrasında 2 adet Entry ve 2 adet Label koyuyorum ve bunların konumlarını, renklerini belirliyorum.
74. satıra dikkat ederseniz burada da textvariable=defaultDatabase ifadesi mevcut. Bunu hepsine koyacağız.
86-87. satırlarda ise butonumuz mevcut. Bu noktada butonumuza command=dropTable diyerek dropTable isimli fonksiyonu verdik. Bu fonksiyon, en başta zaten tanımlı hâlde bekliyor. Şimdi bu fonksiyonu da yazacağız.

Tablo oluştururken yaptığım gibi direkt olarak try-except bloklarını kullandım. Sonrasında iki adet Entry nesnesine girilen verileri get() ile alıp databaseName ve tableName değişkenlerine atadım.
Sonrasında veri tabanına yine aynı yöntemle bağlandım ve bir imleç oluşturdum. Komutumu ise şu şekilde veriyorum:
cursor.execute(f"DROP TABLE {tableName}")
Kullanıcımız, oraya bir tablo ismi girdiğinde (örn. TopManagers) SQL sorgusu şuna dönüşecektir:
DROP TABLE TopManagers
Şimdi, ilk önce çerçevenin konumunu göstereyim, ondan sonra az önce oluşturduğumuz TopManagers tablosunu silmeyi deneyelim.

Gördüğünüz üzere bu çerçevenin gereksinimleri daha az olduğu için biraz küçük kaldı. Zaten bu yüzden onu en sağ tarafa yolladım. Ayrıca dikkat ederseniz; DB Name: kısmı varsayılan olarak employee.db şeklinde geldi; benim yazmama gerek kalmadı.
Şimdi, tabloyu silmeyi deneyelim.

Bize, başarılı olduğumuzu söylüyor; bakalım.

Gerçekten de silinmiş. Kodumuz başarılı bir şekilde çalışmaya devam ediyor. Bir de var olmayan bir tablo silmeyi deneyelim ve ne olacağına bakalım.

Biraz önce sildiğimiz tabloyu tekrar silemedik çünkü artık böyle bir tablo yok. try-except dahil her şey çalışıyor.
Bu kısımda bir tablonun nasıl silindiğini gördük. Bunun için gereken SQL sorgumuzun DROP TABLE <tablo ismi> olduğunu öğrendik. Ancak, nasıl ki tablo oluştururken IF NOT EXISTS yani 'eğer yoksa' diyorsak tablo silerken de 'eğer varsa' diyebiliriz.
DROP TABLE IF EXISTS <tablo ismi> derseniz 'tablo eğer varsa sil' demiş olursunuz ve bu yöntem daha sık tercih edilir ve daha güvenlidir.
Şimdi, bir tabloya çalışan ekleyen çerçeveyi oluşturalım. Bunun için yine belirteçlerimi hazırlıyorum:

Tabloya veri eklemek için gereken SQL sorgusu şöyle idi:
INSERT INTO <tablo ismi> VALUES(<değişken> <değer>...)
O zaman bizim bir veri tabanı ismine, bir tablo ismine, bir de değişkenlere ihtiyacımız var. Yani 3 Label ve 3 Entry daha oluşturmamız lazım. Ayrıca bir butona ihtiyacımız var. Hemen yazalım.

addEmployee() isminde bir fonksiyon oluşturdum ve hemen altına addEmployeeFrame isminde yeni bir çerçeve yarattım. Şimdi, kalan nesneleri de yazalım.

Yukarıdaki kodda bilmediğiniz hiçbir detay olmadığı için geçiyorum. İncelemeniz ve yazmanız yeterli olur.
Şimdi sıra fonksiyonu yazmakta.

Genel olarak hepsi aynı mantıkta. Yalnızca dikkat edelim; ilk kırmızı kutuda VALUES(...) olarak girmemiz gerektiği için VALUES({}) şeklinde bir kullanım sağladım. Bu noktada kullanıcı değer girerken parantez işaretlerini koymak zorunda kalmayacaktır. İkinci kırmızı kutuda ise messagebox içerisine de fstring yapısını entegre edebildiğimizi görebiliyorsunuz. Burada tablo ismi güncel ve dinamik olarak yazılacaktır.
Biraz önce TopManagers tablosunu silmiştik. O yüzden şimdi bir tane daha oluşturacağım ve yazdığım bu kodu kullanarak içerisine veri ekleyeceğim.

Employee Vars: kısmına sırasıyla 'Cyber', 'Worm', 35, 38000.0 değerlerini girdim ve işlemin başarıyla sonuçlandığına dair bir bildirim aldım. Bir de veri tabanına bakalım.

Gerçekten de veri ekleme işlemimiz başarıyla sonuçlanmış. Ancak, değişken girişi esnasında kullanıcının kafasının karışma ihtimaline karşı ona bir yardım butonu ekleyelim.

Burada da bir öncekinde olduğu gibi lambda fonksiyonunu kullandık. Dilerseniz açıklama kısmını daha da detaylandırabilirsiniz.
Son olarak; nasıl gözüktüğünü de görelim.

Veri ekleme işlemleri de tamamlandı. Şimdi, veri silme işlemini yapalım ve size yeni bilgiler katayım. İlk önce belirteçlerimi koyuyorum ve fonksiyonumu hazırlıyorum:

Silme işlemi için gereken SQL sorgumuz şöyle idi:
DELETE FROM <tablo ismi> WHERE <degisken>='<değişken değeri>'
O zaman bizim yine bir veri tabanı ismine, tablo ismine ve değişken değerine ihtiyacımız var. Hemen nesnelerimizi yazalım:

Bütün nesneleri, deleteRowFrame isimli çerçevenin içine koyduk. Yine veri tabanını istediğimiz Entry nesnesine textvariable=defaultDatabase diyerek varsayılan bir değer atadık. Son olarak; butonumuza deleteRow fonksiyonunu verdik. Şimdi, fonksiyonu yazacağız.
Hatırlarsanız size, AUTOINCREMENT yapısından söz etmiştim ve genelde id şeklinde değişkenler tanımladığımızda bu değerin otomatik olarak birer birer artmasını sağladığını söylemiştim. Ancak, SQLITE içerisinde satırların zaten numaralandırıldığını ve otomatik olarak artırıldığını da söylemiştim. Aslında oradaki numaraların ismi ROWID'dir. Row Identifier yani Satır Tanımlayıcı/Numarası olarak geçen bu ifade, gerçekten de işleme alınabilir ve satırları, satır numarasına göre kontrol etmemize olanak tanır. Bu noktada AUTOINCREMENT yapısı kesinlikle küçümsenmemelidir çünkü işe yaradığı çok iyi alanlar vardır ama konumuz bu değil.

cursor.execute(f"DELETE FROM {tableName} WHERE ROWID={int(rowIdentifier)}" komutunu girdik. Bu noktada kullanıcı tablo ismi için TopManagers girerse ve 1. satırdaki kişiyi silmek isterse komut şu hâle dönecektir:
cursor.execute(f"DELETE FROM TopManagers WHERE ROWID=1"
Bu noktada aslında "TopManagers tablosunun birinci satırını sil" demiş oluyoruz ve bunu ROWID ile yapıyoruz. Biz, ROWID=1 demek yerine örneğin name='Cyber' demeyi öğrendik. Ancak, gördüğünüz üzere bu kullanım da oldukça mümkündür. Fakat lütfen dikkat edelim; alacağımız girdiye int() diyerek Type Conversion uyguluyoruz, kullanmasanız da olur ama kullanırsanız daha stabil çalışır. Row Identifier: şeklinde bir Label oluşturmuştuk ama kullanıcı bunun ne olduğunu bilmiyor ya da unutmuş olabilir. O yüzden oraya bir yardım butonu koyabiliriz:

İsterseniz TopManagers tablosuna 1-2 kişi daha ekleyelim ve çerçeveye bakalım.

Şu şekilde, 3 satırdan oluşan bir tablom mevcut.
Çerçevemiz ise şu şekilde:

Şimdi, ikinci satırdaki arkadaşı silelim bakalım.

Silme işleminin başarılı olduğunu söylüyor, bakalım.

İşte bu kadar. Bunu da başarıyla hallettik ve ROWID'nin ne olduğunu öğrenmiş olduk.
Şimdi, veri güncelle işini kodlayalım. Bunun için artık bildiğiniz gibi belirteçlerimi koyuyor ve fonksiyonumu açıyorum.

Şimdi, ilk önce veri güncellememize olanak tanıyan SQL sorgumuzu hatırlayalım:
UPDATE <tablo ismi> SET <verinin güncel hâli> WHERE <güncellenecek veri>
O zaman bizim, veri tabanı ismi, tablo ismi, verinin güncel hâli ve güncellenecek veri olmak üzere 4 adet Label ve 4 adet Entry kullanmamız gerekiyor. Üstüne, güncellenecek veri için bir yardım butonu ve normal buton koymamız lazım. Hemen yazalım.


Her şeyimiz hazır, sadece incelemeniz gerekiyor. Takdir edersiniz ki bütün nesneleri tek tek anlatamam çünkü en başında zaten anlattım. Şimdi, çerçevemize bakalım.

Üçüncü satırda, verinin güncel hâlini yazmasını istiyoruz. Zaten yardım butonunda da bu söyleniyor. Son satırda da kullanıcı, bu değişikliğin kaçıncı satırda olacağını yazmalı.
O hâlde fonksiyonumuzu yazalım:

UPDATE {tableName} SET {variables} WHERE ROWID={rowIdentifier} ifadesi, kullanıcının girdileriyle şu şekle dönüşecektir:
UPDATE TopManagers SET salary=40000.0 WHERE ROWID=1
İsterseniz bir deneme yapalım. Kendime zam yapacağım :).

Parametreleri verdim ve başarılı olduğuna dair bildirim aldım. Dilerseniz veri tabanından da bakalım.

Oldukça başarılı. Şimdi, veri tabanındaki tabloları ve tablolardaki satırları gösteren iki yapı daha oluşturalım. Bu kısımda da yeni şeyler göreceksiniz.
Bunun için belirteçlerimi koyuyorum ve iki farklı fonksiyon açıyorum.

Gördüğünüz üzere bunlardan biri tabloları, diğeri ise tablodaki satırları gösterecek.
Burada aslında pek de bir şeye ihtiyacımız yok. Yalnızca 2 Entry, 2 Label ve 2 butonumuz olacak. Fakat bunları ayrı çerçevelere koymak yerine aynı çerçeveye koyacağım. Önce nesnelerimizi yazalım.

Veri tabanı ismi ve tablo ismini alacak olan 2 Entry ve 2 Label nesnesinden sonra iki fonksiyon için ayrı 2 buton daha koydum. Şimdi, showTables() fonksiyonundan başlayalım.

Butona basıldığında yeni bir pencere açılmasını istediğim için TopLevel() kullandım; bunu daha önce gördünüz. Açtığım yeni pencere de bir nesne olduğu için root, system gibi ona da bir isim verdim ve bu fonksiyon içerisinde olan biten her şey windowInfo nesnesi üzerinden yürüyecek. İkinci kırmızı kutuda, pencerenin başlığına değişken koyabildiğimizi görüyorsunuz. Gerisi bildiğiniz şeyler.

Dikkat edelim; bu fonksiyon tablo isimlerini listeleyecek. Ancak biz şöyle bir komut verdik:
SELECT name FROM sqlite_master WHERE type='table'
Buradaki sqlite_master ifadesi tüm SQLITE veri tabanlarında bulunan bir tablodur. Bu tablonun içinde, bizim oluşturduğumuz tabloların ve diğer her şeyin bir şeması bulunur. Hatta bu şemayı Shell ile görebilirsiniz ama konumuz bu değil; yolu çizdim, yürümek sizin elinizde. Oradaki name değeri ise sqlite_master içerisindeki tabloların adını simgeler. Biz aslında sqlite_master şemasından name değerlerini çekmiş olduk. Ancak elbette, name değerinde başka şeyler de olabilir. Dolayısıyla WHERE type='table' ifadesi ile aradığımız şeyin tablolar olduğunu belirtiyoruz.
Sonrasında fetchall() ile bunları alıyoruz.
Sonrasında, kutu içerisine almadığım bir detay söz konusu; 260-261. satırdaki Text. Label yapısının bir türü olan Text nesnesi oldukça işlevli ve çok satırlı ifadeler için ideal bir yapıdır. Birazdan bu konuda ne demek istediğimi anlayacaksınız. Tanımlaması Label gibidir. Yalnızca oraya Text() yazmanız gerekir. Ayrıca, dikkat ederseniz Text(system) yerine Text(windowInfo) yazdık. Çünkü bu, yeni pencerede işlem görecek.

Tabloları sırayla yazdıracağız, öyle değil mi? Dolayısıyla burada bir for döngüsü oldukça işe yarayacaktır. Sıralama konusunda enumerate() fonksiyonunu kullandım ve ona 1 değerini verdim. Hatırlarsanız enumerate(), sıralamaya sıfırdan başlıyordu ama biz oraya 1 değerini girebiliyorduk.
Sonrasında gelen print(i) ifadesi tamamen test amaçlı orada unuttuğum bir koddur; önemsemeyin.
Son olarak, tablesInfoText.insert(END, f"{i}\n") ifadesini görüyorsunuz. insert() metodu, ifadeler arasına karakter yerleştirmeye olanak tanır. Bu noktada biz de Text nesnesine for döngüsü ile kontrol ettiğimiz tablo isimlerini yerleştirdik (i) ve \n özel kaçış karakteri ile bunların alt alta girilmesini sağladık.
Son olarak bağlantıyı sonlandırıyoruz ve işimiz bitiyor. Dilerseniz bunu test edelim ama tek bir tablomuz mevcut. O yüzden ben 1-2 adet tablo daha oluşturup öyle deneyeceğim.

Sol tarafta daha önce yazdığımız kodlar sayesinde 2 farklı tablo oluşturdum ve öylesine değerler girdim. Şimdi, sağdaki çerçeveyi görüyorsunuz; bizim derdimiz Show Tables butonu ile. Dolayısıyla yalnızca veri tabanı ismi yeterli olacaktır; veri tabanındaki tabloları görüntüleyeceğiz. Butona basalım bakalım.

Oldukça başarılı bir çıktı geldiğini görüyorsunuz. Pencerenin başlığına bakarsanız veri tabanının isminin de yazıldığını görürsünüz. Ayrıca sıralamaya 0'dan değil, 1'den başlandığını da görürsünüz.
Şimdi, showRows() isimli fonksiyona bir bakalım.

Burada değişen şey SQL sorgusudur. Bildiğiniz SELECT * FROM <tablo ismi> yapısını kurduk. Şimdi, bir tablo ismi verelim ve içerisinde neler olduğunu görelim.

Gördüğünüz üzere açılan yeni pencerenin başlığı da çıktısı da gayet başarılı bir şekilde geldi.
Bir de ben, şöyle bir şey yapmak istedim:


İletişim bilgisi de bıraktım. Bu tamamen size kalmış, istemezseniz yapmayabilirsiniz.
Hatırlarsanız bizim bir giriş yapma sayfamız vardı. İşte şimdi, bu iki kodu birbirine entegre edeceğiz ve bu sayede yeni bir şey öğrenmiş olacaksınız.
Bunun için login.py dosyasına gidiyorum ve giriş işleminin başarılı olduğu koşulu buluyorum. Sonrasında oraya şu basit kod parçasını koyuyorum:

exec ifadesi, execute kelimesinden gelir. İçerisine verdiğiniz bir python dosyasını uygun koşullarda çalıştıracaktır. .read(), verdiğiniz .py dosyasını okuyacaktır ve open() onu açacaktır.
Bunu göstermek için bir Reel videosu çektim. Dilerseniz şu linki takip ederek videoyu izleyebilirsiniz: https://www.instagram.com/reel/Cn-eeRJDo0d/?igshid=OGQ2MjdiOTE=
Takdir edersiniz ki bu kodu 1 günden daha kısa sürede yazdım ve asıl amacım size hem yeni şeyler öğretmek hem de eski konuları tekrar etmekti. Aşağıda vereceğim önerileri ben yapmadım ama size, zaman ayırıp yapmanızı tavsiye ediyorum; bu, size inanılmaz bir ivme kazandıracaktır. Elbette, aşağıdaki maddelerden bazıları birkaç dakikalık işler ama dediğim gibi; derdim aynı kodları sık sık yazıp göz ve el alışkanlığınızı artırmaktı. Sevgiler, başarılar.
Şimdi, kodun kesintisiz hâlini ekran görüntüsü olarak değil, metin olarak atacağım.
login.pyfrom tkinter import *from tkinter import messageboximport sqlite3root = Tk()root.geometry("400x450")root.title("Cyber Worm")root.iconbitmap("C:/Python/EMS/logo.ico")root.configure(bg="#005b96")connection = sqlite3.connect("admins.db")myCursor = connection.cursor()
############################################## LOGIN ##############################################def loginButton(): myCursor.execute("SELECT username FROM administrators") results = myCursor.fetchall() for result in results: for selected in result: if usernameEntry.get() in selected: myCursor.execute(f"SELECT password FROM administrators WHERE username='{selected}'") passwd = myCursor.fetchall() if passwordEntry.get() == passwd[0][0]: messagebox.showinfo("System Message", "Successfully logged in.") exec(open("employee.py").read()) else: return messagebox.showinfo("System Message", "Username or password is wrong.")welcomeLabel = Label(root, text="Welcome.", font=('Arial', 20, 'bold'), bg='#005b96', fg='red', pady=100).pack()usernameLabel = Label(root, text="Username: ", font=('Arial', 14), bg='#005b96', fg='white')usernameLabel.place(relx=0.1, rely=0.4)passwordLabel = Label(root, text="Password: ", font=('Arial', 14), bg='#005b96', fg='white')passwordLabel.place(relx=0.1, rely=0.5)usernameEntry = Entry(root, width=30, border=5)usernameEntry.place(relx=0.4, rely=0.4)passwordEntry = Entry(root, width=30, border=5, show="*")passwordEntry.place(relx=0.4, rely=0.5)enterButton = Button(root, text="Log In", width=43, height=2, command=loginButton).place(relx=0.1, rely=0.6)############################################## LOGIN ##############################################if __name__ == "__main__": root.mainloop() connection.close()
employee.pyfrom tkinter import *from tkinter import messageboximport sqlite3import webbrowser as websystem = Tk()system.geometry("1920x1080")system.title("Cyber Worm")system.iconbitmap("C:/Python/EMS/logo.ico")system.configure(bg="#005b96")#system.attributes('-fullscreen', True)defaultDatabase = StringVar()defaultDatabase.set("employee.db")titleLabel = Label(system, text="EMPLOYEE MANAGEMENT SYSTEM (EMS)", bg='#005b96', fg='red', font=('Arial', 35, 'bold'))titleLabel.place(relx=0.15, rely=0.03)########################################### CREATE TABLE AND ADD VARIABLE ###########################################def createTableMethod(): try: databaseName = getDbNameEntryCREATE.get() tableName = getTableNameEntryCREATE.get() variables = getVariablesEntryCREATE.get() connection = sqlite3.connect(f'{databaseName}') cursor = connection.cursor() cursor.execute(f"CREATE TABLE IF NOT EXISTS {tableName} {variables}") connection.commit() connection.close() return messagebox.showinfo("System Message", "Table is created successfully.") except: return messagebox.showerror("System Message", "Something went wrong.")createTableFrame = LabelFrame(system, text="Create Table", fg='white', bg='#005b96', font=('Arial', 12), height=220, width=320)createTableFrame.place(relx=0.05, rely=0.14)getDbNameEntryCREATE = Entry(createTableFrame, textvariable=defaultDatabase, border=5)getDbNameEntryCREATE.place(relx=0.5, rely= 0.1)getDbNameLabelCREATE = Label(createTableFrame, text="DB Name:", bg='#005b96', fg='white', font=('Arial', 12, 'bold'))getDbNameLabelCREATE.place(relx=0.05, rely=0.1)getTableNameEntryCREATE = Entry(createTableFrame, border=5)getTableNameEntryCREATE.place(relx=0.5, rely= 0.3)getTableNameLabelCREATE = Label(createTableFrame, text="Table Name:", bg='#005b96', fg='white', font=('Arial', 12, 'bold'))getTableNameLabelCREATE.place(relx=0.05, rely=0.3)getVariablesLabelCREATE = Label(createTableFrame, text="Variables:", bg='#005b96', fg='white', font=('Arial', 12, 'bold'))getVariablesLabelCREATE.place(relx=0.05, rely=0.5)getVariablesEntryCREATE = Entry(createTableFrame, border=5)getVariablesEntryCREATE.place(relx=0.5, rely= 0.5)helpButtonCREATE = Button(createTableFrame, text="? ", font=('Arial', 10, 'bold'), bg='red', fg='white', \ command=lambda : messagebox.showinfo("Usage", "USAGE: (<variable name> <data type>,...)\ \nYou can take support from your manager."))helpButtonCREATE.place(relx=0.4, rely=0.5)createTableButton = Button(createTableFrame, text="Create Table", fg='#005b96', width=40, height=2, command=createTableMethod)createTableButton.place(relx=0.05, rely=0.75)########################################### CREATE TABLE AND ADD VARIABLE ###################################################################################### DELETE TABLE ###########################################def dropTable(): try: databaseName = getDbNameEntry_DropTable.get() tableName = getTableNameEntry_DropTable.get() connection = sqlite3.connect(f'{databaseName}') cursor = connection.cursor() cursor.execute(f"DROP TABLE {tableName}") connection.commit() connection.close() return messagebox.showinfo("System Message", "Table is deleted successfully.") except: return messagebox.showerror("System Message", "Something went wrong.")dropTableFrame = LabelFrame(system, text="Delete Table", fg='white', bg='#005b96', font=('Arial', 12), height=170, width=320) dropTableFrame.place(relx=0.7, rely=0.2)getDbNameEntry_DropTable = Entry(dropTableFrame, textvariable=defaultDatabase, border=5)getDbNameEntry_DropTable.place(relx=0.5, rely= 0.1)getDbNameLabel_DropTable = Label(dropTableFrame, text="DB Name:", bg='#005b96', fg='white', font=('Arial', 12, 'bold'))getDbNameLabel_DropTable.place(relx=0.05, rely=0.1)getTableNameEntry_DropTable = Entry(dropTableFrame, border=5)getTableNameEntry_DropTable.place(relx=0.5, rely= 0.4)getTableNameLabel_DropTable = Label(dropTableFrame, text="Table Name:", bg='#005b96', fg='white', font=('Arial', 12, 'bold'))getTableNameLabel_DropTable.place(relx=0.05, rely=0.4)dropTableButton = Button(dropTableFrame, text="Delete Table", fg='#005b96', width=40, height=2, command=dropTable)dropTableButton.place(relx=0.05, rely=0.69)########################################### DELETE TABLE ###################################################################################### DELETE ROW ###########################################def deleteRow(): try: databaseName = getDbNameEntry_DeleteRow.get() tableName = getTableNameEntry_DeleteRow.get() rowIdentifier = getRowEntry_DeleteRow.get() connection = sqlite3.connect(f'{databaseName}') cursor = connection.cursor() cursor.execute(f"DELETE FROM {tableName} WHERE ROWID={int(rowIdentifier)}") connection.commit() connection.close() return messagebox.showinfo("System Message", f"Employee is removed from {tableName} successfully.") except: return messagebox.showerror("System Message", "Something went wrong.")deleteRowFrame = LabelFrame(system, text="Delete Row", fg='white', bg='#005b96', font=('Arial', 12), height=220, width=320) deleteRowFrame.place(relx=0.05, rely=0.5)getDbNameEntry_DeleteRow = Entry(deleteRowFrame, textvariable=defaultDatabase, border=5)getDbNameEntry_DeleteRow.place(relx=0.5, rely= 0.1)getDbNameLabel_DeleteRow = Label(deleteRowFrame, text="DB Name:", bg='#005b96', fg='white', font=('Arial', 12, 'bold'))getDbNameLabel_DeleteRow.place(relx=0.05, rely=0.1)getTableNameEntry_DeleteRow = Entry(deleteRowFrame, border=5)getTableNameEntry_DeleteRow.place(relx=0.5, rely= 0.3)getTableNameLabel_DeleteRow = Label(deleteRowFrame, text="Table Name:", bg='#005b96', fg='white', font=('Arial', 12, 'bold'))getTableNameLabel_DeleteRow.place(relx=0.05, rely=0.3)getRowEntry_DeleteRow = Entry(deleteRowFrame, border=5)getRowEntry_DeleteRow.place(relx=0.5, rely=0.5)getRowLabel_DeleteRow = Label(deleteRowFrame, text="Row Identifier:", bg='#005b96', fg='white', font=('Arial', 11, 'bold'))getRowLabel_DeleteRow.place(relx=0.05, rely=0.5)helpButton_DeleteRow = Button(deleteRowFrame, text="? ", font=('Arial', 10, 'bold'), bg='red', fg='white', \ command=lambda : messagebox.showinfo("Usage", "USAGE: The number of the record to be deleted.\ \nYou can take support from your manager."))helpButton_DeleteRow.place(relx=0.4, rely=0.5)deleteRowButton = Button(deleteRowFrame, text="Delete Row", fg='#005b96', width=40, height=2, command=deleteRow)deleteRowButton.place(relx=0.05, rely=0.74)########################################### DELETE ROW ###################################################################################### SHOW TABLES OR ROWS ###########################################def showTables(): windowInfo = Toplevel() windowInfo.geometry("1920x1080") windowInfo.title(f"Table's ({getDbNameEntry_Table.get()}) rows.") windowInfo.iconbitmap("C:/Python/EMS/logo.ico") windowInfo.configure(bg="#005b96") databaseName = getDbNameEntry_Table.get() connection = sqlite3.connect(f'{databaseName}') cursor = connection.cursor() # show tables cursor.execute(f"SELECT name FROM sqlite_master WHERE type='table'") tables = cursor.fetchall() tablesInfoText = Text(windowInfo, bg='#005b96', fg='white' ,font=('Arial', 12, 'bold'), width=80, height=15) tablesInfoText.pack() for i in enumerate(tables, 1): tablesInfoText.insert(END, f"{i}\n") connection.close()def showRows(): windowInfo = Toplevel() windowInfo.geometry("1920x1080") windowInfo.title(f"Table's ({getTableNameEntry_Row.get()}) rows.") windowInfo.iconbitmap("C:/Python/EMS/logo.ico") windowInfo.configure(bg="#005b96") databaseName = getDbNameEntry_Table.get() tableName = getTableNameEntry_Row.get() connection = sqlite3.connect(f'{databaseName}') cursor = connection.cursor() cursor.execute(f"SELECT * FROM {tableName}") rows = cursor.fetchall() rowInfoText = Text(windowInfo, bg='#005b96', fg='white' ,font=('Arial', 12, 'bold'), width=80, height=15) rowInfoText.pack() for i in enumerate(rows, 1): rowInfoText.insert(END, f"{i}\n") connection.close()showTablesOrRowsFrame = LabelFrame(system, text="Show Tables or Rows", fg='white', bg='#005b96', font=('Arial', 12), height=220, width=320) showTablesOrRowsFrame.place(relx=0.4, rely=0.14)getDbNameEntry_Table = Entry(showTablesOrRowsFrame, textvariable=defaultDatabase, border=5)getDbNameEntry_Table.place(relx=0.5, rely= 0.1)getDbNameLabel_Table = Label(showTablesOrRowsFrame, text="DB Name:", bg='#005b96', fg='white', font=('Arial', 12, 'bold'))getDbNameLabel_Table.place(relx=0.05, rely=0.1)getTableNameEntry_Row = Entry(showTablesOrRowsFrame, border=5)getTableNameEntry_Row.place(relx=0.5, rely= 0.38)getTableNameLabel_TableOrRow2 = Label(showTablesOrRowsFrame, text="Table Name:", bg='#005b96', fg='white', font=('Arial', 12, 'bold'))getTableNameLabel_TableOrRow2.place(relx=0.05, rely=0.38)showTablesButton = Button(showTablesOrRowsFrame, text="Show Tables", fg='#005b96', width=20, height=4, command=showTables)showTablesButton.place(relx=0.02, rely=0.62)showRowsButton = Button(showTablesOrRowsFrame, text="Show Table's Rows", fg='#005b96', width=20, height=4, command=showRows)showRowsButton.place(relx=0.51, rely=0.62)########################################### SHOW TABLES OR ROWS ###################################################################################### ADD EMPLOYEE ###########################################def addEmployee(): try: databaseName = getDbNameEntry_addEmployee.get() tableName = getTableNameEntry_addEmployee.get() variables = getVarsEntry_addEmployee.get() connection = sqlite3.connect(f'{databaseName}') cursor = connection.cursor() cursor.execute(f"INSERT INTO {tableName} VALUES({variables})") connection.commit() connection.close() return messagebox.showinfo("System Message", f"Employee is added to {tableName} successfully.") except: return messagebox.showerror("System Message", "Something went wrong.")addEmployeeFrame = LabelFrame(system, text="Add Employee", fg='white', bg='#005b96', font=('Arial', 12), height=220, width=320) addEmployeeFrame.place(relx=0.4, rely=0.5)getDbNameEntry_addEmployee = Entry(addEmployeeFrame, textvariable=defaultDatabase, border=5)getDbNameEntry_addEmployee.place(relx=0.5, rely= 0.1)getDbNameLabel_addEmployee = Label(addEmployeeFrame, text="DB Name:", bg='#005b96', fg='white', font=('Arial', 12, 'bold'))getDbNameLabel_addEmployee.place(relx=0.05, rely=0.1)getTableNameEntry_addEmployee = Entry(addEmployeeFrame, border=5)getTableNameEntry_addEmployee.place(relx=0.5, rely= 0.3)getTableNameLabel_addEmployee = Label(addEmployeeFrame, text="Table Name:", bg='#005b96', fg='white', font=('Arial', 12, 'bold'))getTableNameLabel_addEmployee.place(relx=0.05, rely=0.3)getVarsEntry_addEmployee = Entry(addEmployeeFrame, border=5)getVarsEntry_addEmployee.place(relx=0.5, rely=0.5)getVarsLabel_addEmployee = Label(addEmployeeFrame, text="Employee Vars:", bg='#005b96', fg='white', font=('Arial', 11, 'bold'))getVarsLabel_addEmployee.place(relx=0.05, rely=0.5)addEmployeeButton = Button(addEmployeeFrame, text="Add Employee", fg='#005b96', width=40, height=2, command=addEmployee)addEmployeeButton.place(relx=0.05, rely=0.74)helpButton_addEmployee = Button(addEmployeeFrame, text="? ", font=('Arial', 10, 'bold'), bg='red', fg='white', \ command=lambda : messagebox.showinfo("Usage", "USAGE: <variable's value>, ...\ \nYou can take support from your manager."))helpButton_addEmployee.place(relx=0.42, rely=0.5)########################################### ADD EMPLOYEE ###################################################################################### UPDATE DATA ###########################################def updateData(): try: databaseName = getDbNameEntry_update.get() tableName = getTableNameEntry_update.get() variables = getVarsEntry_update.get() rowIdentifier = getRowEntry_update.get() connection = sqlite3.connect(f'{databaseName}') cursor = connection.cursor() cursor.execute(f"UPDATE {tableName} SET {variables} WHERE ROWID={rowIdentifier}") connection.commit() connection.close() return messagebox.showinfo("System Message", f"Employee is updated successfully.") except: return messagebox.showerror("System Message", "Something went wrong.")updateFrame = LabelFrame(system, text="Update Employee", fg='white', bg='#005b96', font=('Arial', 12), height=260, width=320) updateFrame.place(relx=0.7, rely=0.5)getDbNameEntry_update = Entry(updateFrame, textvariable=defaultDatabase, border=5)getDbNameEntry_update.place(relx=0.5, rely= 0.05)getDbNameLabel_update = Label(updateFrame, text="DB Name:", bg='#005b96', fg='white', font=('Arial', 12, 'bold'))getDbNameLabel_update.place(relx=0.05, rely=0.05)getTableNameEntry_update = Entry(updateFrame, border=5)getTableNameEntry_update.place(relx=0.5, rely= 0.22)getTableNameLabel_update = Label(updateFrame, text="Table Name:", bg='#005b96', fg='white', font=('Arial', 12, 'bold'))getTableNameLabel_update.place(relx=0.05, rely=0.22)getVarsEntry_update = Entry(updateFrame, border=5)getVarsEntry_update.place(relx=0.5, rely=0.4)getVarsLabel_update = Label(updateFrame, text="To Be Updated:", bg='#005b96', fg='white', font=('Arial', 11, 'bold'))getVarsLabel_update.place(relx=0.05, rely=0.4)getRowEntry_update = Entry(updateFrame, border=5)getRowEntry_update.place(relx=0.5, rely=0.6)getRowLabel_update = Label(updateFrame, text="Row Identifier:", bg='#005b96', fg='white', font=('Arial', 12, 'bold'))getRowLabel_update.place(relx=0.05, rely=0.6)helpButton_update = Button(updateFrame, text="? ", font=('Arial', 10, 'bold'), bg='red', fg='white', \ command=lambda : messagebox.showinfo("Usage", "USAGE: <variable>='<value>'\ \nYou can take support from your manager."))helpButton_update.place(relx=0.42, rely=0.4)UpdateButton = Button(updateFrame, text="Update Employee", fg='#005b96', width=40, height=2, command=updateData)UpdateButton.place(relx=0.05, rely=0.78)########################################### UPDATE DATA ###################################################################################### CONTACT ###########################################def contact(): web.open("https://blog-cyberworm.com/blog/telegram-instagram")contactFrame = LabelFrame(system, text="Contact", fg='white', bg='#005b96', font=('Arial', 12), height=100, width=900)contactFrame.place(relx=0.05, rely=0.8)contactLabel = Label(contactFrame, text="I can edit this code in a more efficient, effective and advanced way.\nThis code just for the practice and education. Contact me if you want:", \ font=('Arial', 14, 'bold'), bg='#005b96', fg='red')contactLabel.place(relx=0.01, rely=0.1)contactButton = Button(contactFrame, text="Contact", fg='#005b96', width=30, height=2, command=contact)contactButton.place(relx=0.75, rely=0.2)########################################### CONTACT ###########################################if __name__ == "__main__": system.mainloop()
Yayınlanma Tarihi: 2023-01-28 14:06:00
Son Düzenleme Tarihi: 2023-04-02 19:08:46