Python acemisinden Notlar: 7-Pencere Tasarımı 2

Endorfin35+

Kayıtsız Üye
Staff member
Katılım
1 Mayıs 2020
Mesajlar
2,954
Bir programa arayüz hazırlamak için bu kadar çok şey öğrenmek hala bana saçma ve gereksiz geliyor. Sadece basit bir windows programı için arayüze ihtiyaç var ise visual studio veya autoit ile tasarım yapmak daha pratik seçimler. Bununla birlikte yazacağım programın birden çok platformda çalışmasına ihtiyacım var bu nedenle biraz öğrenme zahmetine değer olduğunu düşünüyorum.

Qtdsigner ve python ile pencere oluşumu konusunu tekrar inceleyerek bazı detayları bu konuda aktarmaya karar verdim.

Adım 1 : Qtdesigner ile Main Window formu oluşturuyoruz.

1617436194882.png


Adım 2 : form üzerine istedeiğimiz objeleri yerleştirip görsel tasarımı yapıyoruz. Bu noktada önemli olan obje adlarına dikkat etmek gerekir ise düzenlemek. Ben deneme için iki adet obje ekledim adları : "lineEdit" ve "pushButton"

1617436301001.png


Adım 3 : Söz konusu deneme projemiz için bir klasör oluşturup hazırladığımız form'u bu klasör içerisine kaydediyoruz.

1617436571872.png


Adım 4 : Code editörümüzü açarak işleme devam ediyoruz. Ben tercihim Visual Studio Code oldu. Proje klasörünü açıyoruz.

1617436834309.png


Adım 5 : ui uzantılı olan pencere tasarımını python ile kullanmak için pencere tasarım kodlarının "uic" kütüphanesi ilepython kodlarına dönüştürülmesi gerekiyor. Bu aşama da iki farklı şekilde devam etmek mümkün. Ya dönüşüm her defasında çalışma zamanı içersinde yapılacak yada önceden dönüşüm sağlanacak. Ben önceden dönüşümü daha mantıklı buluyorum. Bu şekilde hem çalıma zamanı içerisinde program dönüşüm ile uğraşmayacak hemde neyin nerden geldiğine daha hakim olabileceğiz. İki yönteminde nasıl çalıştığını şu konudaki örnekte bulabilirsiniz:

Kodları önceden dönüştürmek için çalışma klasörü içerisinde "ana_pen_to_py.py" adlı bir dosya oluşturup kodları aşağıdaki şekilde düzenliyoruz ve kodu çalıştırıyoruz. Kodu çalıştırdıktan sonra çalışma klasörü içerisinde py uzantılı pencere tasarımı dosyamız oluşacaktır.

1617437458388.png


Python:
from PyQt5 import uic

with open ("ana_pen_ui.py","w",encoding="utf-8") as f:
    uic.compileUi("ana_pencere.ui",f)

Bu noktada dosyları adlandırma hakkında benimsediğim yöntemden bahsetmek istiyorum. Tek bir pencere içeren bir program hazırlanacak ise çok fazla sorun yok ancak birden çok pencere tasarımı ile uğraşılacak ise her pencere için ui dosyasını py dosyasına dönüşüm sağlayan to_py.py yardımcı dosyamız ayrı ayrı hazırlanmalı. böylece kod yazarken herhangi bir noktada görsel tasarım aşamasına geri dönülmek istendiğinde düzenlemeler çok daha sorunsuz olacaktır.

ana_pencere.ui : ui uzantılı tasarım dosyası uzantısı zaten ui olduğu için sadece dosya adının ana pencereyi ifade etmesi yeterli.
ana_pen_to_py : to_py kısaltması ise python koduna dönüşüm olacağını bana hatırlatıyor. başa ise hangi dosya için olduğunu ekliyorum.
ana_pencere_ui.py : program geliştikçe çalışma klasörü içerisinde bir çok py uzantılı dosya olacak. karışıklığı önlemek için dosya adı sonuna _ui eklerek bunun bir tasarım dosyası (ui= user interface) olduğunu bana hatırlatmasını sağlıyorum.

Siz dosya adlarını istediğiniz gibi verebilirsiniz. Yeterki dosyalarınıza hakim olabileceğiniz adlandırmalar kullanın...

Adım 6: py uzantılı tasarım kodları üzerinde bazı değişiklikler yapmak ihtiyacımız olacak. "ana_pencere_ui.py" dosyasını doğrudan düzenleyerek istediğimiz değişiklikleri yapabiliriz ancak bu çok iyi bir fikir değil. Geriye dönüp qt designer ile tasarımda bir değişiklik yapıp tekrar ui uzantılı dosya oluşturup tekrar py dosyasına dönüştürdüğümüzde yaptığımız düzenlemeler kaybolacaktır. Bu nedenle Şu ana kadar oluşturduğumuz üç dosyaya sonradan kesinlikle müdahale etmemeliyiz.

İstediğimiz düzenlemeleri yapmak için yeni bir py dosyası ekleyerek dosya adını "ana_pen_code_ui.py" şeklinde veriyoruz. bu dosya düzenleme yaptığımız ve kodlarımız yazdığımız dosyamız olacak. Bu dosya içerisine "ana_pencere_ui.py" dosyasındaki kodları dahil ederek çalışacağımızdan sonradan yapmak isteyeceğimiz değişiklikler bizim için sorun olmayacak.

Dosya içeriğimizi aşağıdaki gibi oluşturmalıyız. Öncelikle uic kütüphanesi tarafından oluşturulan "ana_pencere_ui.py" dosyasındaki python kodlarına göz atalım. kod içerisinde "Ui_MainWindow" adında bir sınıf oluşturulmuş. Bu sınıf adı bizim için önemli ve kendi kodlarımız içinde kullanacağız. Ayrıca Pyqt5 paketinden QtCore, QtGui, QtWidgets koda dahil edilmiş.

1617439109142.png


aşağıdaki kodlarda daha belirgin olması için "Ui_MainWindow" sınıf adını miras değişkenine aldım. Doğrudanda kullanılabilirdi.
Pencere başlığını ve buton yazısını yeniden düzenledik. Butonun obje adının "pushButton" olarak nereden geldiğini 2. adımda göstermiştim.

Python:
import ana_pen_ui      # py dönüşüm ile oluşan python kodlarını bu dosyaya dahil et.
import sys             # sys kütüphanesi dahil et.
from PyQt5.QtWidgets import QMainWindow, QApplication
# uic (QtDesigner den..) ile oluşan sınıf sadece tasarım öğelerini barındırıyor. Bu dosyada uygulama ve pencere
# oluşturulacağı için yukarıdaki kütüphaneleri koda ayrıca dahil ediyoruz.
# uic ile oluşturulan sınıf ı miras alacağımızdan sınıf adını miras adınaki değişkene alıyoruz.
miras = ana_pen_ui.Ui_MainWindow
# AnaPencere adında yeni bir sınıf oluşturarak QMainWindow ve uic tarafından oluşturan Ui_MainWindow
# sınıflarını miras alıyoruz.
class AnaPencere(QMainWindow,miras):
    def __init__(self):
        super().__init__()      #super() fonksiyonu ile QMainWindow methodlarını alıyoruz/koruyoruz.
        self.setupUi(self)      # setupUi(self) fonksiyonu uic ile oluşan Ui_MainWindow fonksiyonu
        self.init_form()        # kendi init foksiyonumuz çağırıyoruz.

    def init_form(self):
        self.setWindowTitle("Ana Pencere Formu")    # düzenlemeler...
        self.pushButton.setText("BUTON")            # düzenlemeler...
# bir uygulama oluşturmak için QApplication sınıfından (sys.argv) ile bir uygulama nesnesi oluşturuyoruz.
uygulama = QApplication(sys.argv)
# artık bir uygulmamaız var.
# yazdığımız AnaPencere sınıfını örnekleyerek pencere nesnemizi oluşturuyoruz.
pencere = AnaPencere()
# artık birde penceremiz var.

pencere.show()   # penecereyi göster.
sys.exit(uygulama.exec_())  # pencerenin X butonuna basılır ise uygulamayı sonlandır.

1617443282512.png


Bu noktada neyin nereden geldiğini anlayarak penceremizi oluşturduk. Python ve qt ile çalışmak gerekli ise kesinlikle pythonda oop nasıl işliyor anlamak gerekli. Bu konuyuda notlar 4 de bulabilirsiniz.


Projenin dosyaları ektedir.
 

Ekler

  • Pencere olusturma 1.zip
    4.7 KB · Görüntüleme: 55
Son düzenleme:

Endorfin35+

Kayıtsız Üye
Staff member
Katılım
1 Mayıs 2020
Mesajlar
2,954
Projemizi geliştirmek adını örneğimizi de geliştirerek devam edelim...

Adım 1 : Qtdesigner ile bir adet de Widget formu oluşturuyoruz.

1617444638813.png


Adım 2 : yeni formumuza yine bir adet buton ve metin kutusu ekliyoruz. Ben kolaya kaçarak kopyala yapıştır yaptım.

1617444779934.png


Adım 3 : yeni formu mevut çalışma klasörüne "yan_pencere" adı ile kaydediyoruz.

1617444875638.png


Adım 4 : Editöre geçerek "yan_pencere.ui" dosyamız için yeni bir to_py dosyası oluşturarak pencere tasarımını içeren "yan_pen_ui.py" dosyamızı oluşturuyoruz.

1617445122916.png


Bu aşamada olayı daha iyi anlamak için "ana_pen_ui.py" ve "yan_pen_ui.py" dosya içeriklerine göz atalım...

1617445466584.png


Kodlar arasında teknik olarak ciddi bir fark yok. bir dosyada "Ui_MainWindow" adı ile bir sınıf oluşturularak sınıf içerisinde "MainWindow" değişkeni kullanılırken diğerinde ise "Ui_Form" adı kullanılarak "Form" değişkeni kullanılmış.

Bu sınıflar oluşturulur iken miras alma (Inheritance) yerine dahil etme (composition) yöntemi kullanılmış. Dahil edilen sınıflarda tamamen aynı olan "PyQt5" paketinden "QtCore", "QtGui", "QtWidgets" sınıfları....

Bu kodlar QtDesigner ve uic tarafındna otomatik oluşturulduğundan bu kısım ile çok fazla bir işimiz yok...

Adım 5 : kendi düzenleme ve kodlamalarımız için "yan_pen_code_ui.py" adlı bir dosya oluşturup içeriğiniz düzenliyoruz. Temel olarak yukarıdaki adımları tekrarlıyoruz.

1617446201939.png


Bu aşamada aynı proje içerisinde birbirinden bağımsız iki adet pencere elde etmiş olduk. Penceremizin biri "Main Window" Teması ile oluşturulur iken diğeri "Widget" teması ile oluşturulmuş oldu...
 

Endorfin35+

Kayıtsız Üye
Staff member
Katılım
1 Mayıs 2020
Mesajlar
2,954
Pencereler arasında ilişki kurarak örneğimize devam edelim.

Adım 1 : Öncelikle "ana_pen_code_ui.py" Dosyasını yeniden düzenleyerek sınıf oluşturma kodlarından sonrasını siliyoruz.

1617461037141.png


Böylece bu dosya içerisinde herhangi bir uygulama oluşturmuyor, pencere sınıfını örneklemiyoruz. Ardından aynı işlemi "yan_pen_code_ui.py" dosyası içinde yapıyoruz.

Adım 2 : "yan_pen_code_ui.py" dosyasındaki sınıf kodlarını aşağıdaki gibi düzenleyelim. Buradaki düzenleme yardımcı pencere üzerindeki butona basıldığında yardımcı pencerenin kapanmasını sağlamaktan ibarettir.

Python:
import yan_pen_ui      # py dönüşüm ile oluşan python kodlarını bu dosyaya dahil et.
# import sys             # sys kütüphanesi dahil et.
from PyQt5.QtWidgets import QMainWindow #, QApplication
# uic (QtDesigner den..) ile oluşan sınıf sadece tasarım öğelerini barındırıyor. Bu dosyada uygulama ve pencere
# oluşturulacağı için aşağıdaki kütüphaneleri koda ayrıca dahil ediyoruz.

# uic ile oluşturulan sınıf ı miras alacağımızdan sınıf adını miras adınaki değişkene alıyoruz.
miras = yan_pen_ui.Ui_Form

# AnaPencere adında yeni bir sınıf oluşturarak QMainWindow ve uic tarafından oluşturan Ui_MainWindow
# sınıflarını miras alıyoruz.
class YanPencere(QMainWindow,miras):
    def __init__(self):
        super().__init__()      #super() fonksiyonu ile QMainWindow methodlarını alıyoruz/koruyoruz.
        self.setupUi(self)      # setupUi(self) fonksiyonu uic ile oluşan Ui_MainWindow fonksiyonu
        self.init_form()        # kendi init foksiyonumuz çağırıyoruz.
 
    def init_form(self):
        self.setWindowTitle("Yardımcı Pencere Formu")    # düzenlemeler...
        self.pushButton.setText("BUTON")            # düzenlemeler...
 
        # yardımcı pencere üzerindeki butona basılır ise YanPen_Btn() fonksiyonunu çalıştır.
        self.pushButton.clicked.connect(self.YanPen_Btn)
 
    # yardımcı pencere buton fonksiyonu
    def YanPen_Btn(self):
        self.hide()         # kendini kapat/gizle.

Adım 3 : "ana_pen_code_ui.py" dosyasını aşağıdaki şekilde düzenleyelim. Öncelikle yan_pen_code_ui dosyasından YanPencere sınıfını dosyaya dahil edelim. Sonrasında dosya içerisinde tanımladığımız AnaPencere sınıfına YanPencere sınıfını dahil edelim (composition) ve ana pencere üzerindeki butona tıklandığında yardımcı pencerenin görüntülemesini sağlayalım. Kod içerisinde yeterli açıklama mevcuttur.

Python:
import ana_pen_ui      # py dönüşüm ile oluşan python kodlarını bu dosyaya dahil et.
from yan_pen_code_ui import YanPencere # yan pencere sınıfını dahil et.
#import sys             # sys kütüphanesi dahil et.
from PyQt5.QtWidgets import QMainWindow #, QApplication
# uic (QtDesigner den..) ile oluşan sınıf sadece tasarım öğelerini barındırıyor. Bu dosyada uygulama ve pencere
# oluşturulacağı için aşağıdaki kütüphaneleri koda ayrıca dahil ediyoruz.

# uic ile oluşturulan sınıf ı miras alacağımızdan sınıf adını miras adınaki değişkene alıyoruz.
miras = ana_pen_ui.Ui_MainWindow

# AnaPencere adında yeni bir sınıf oluşturarak QMainWindow ve uic tarafından oluşturan Ui_MainWindow
# sınıflarını miras alıyoruz.
class AnaPencere(QMainWindow,miras):
    def __init__(self):
        super().__init__()      #super() fonksiyonu ile QMainWindow methodlarını alıyoruz/koruyoruz.
        self.setupUi(self)      # setupUi(self) fonksiyonu uic ile oluşan Ui_MainWindow fonksiyonu
        self.init_form()        # kendi init foksiyonumuz çağırıyoruz.
 
    def init_form(self):
        self.setWindowTitle("Ana Pencere Formu")    # düzenlemeler...
        self.pushButton.setText("BUTON")            # düzenlemeler...
     
        self.yan_pencerem = YanPencere()
     
        self.pushButton.clicked.connect(self.yan_pecere_ac)
     
     
        #self.yan_pencerem.show()
     
    def yan_pecere_ac(self):
        self.yan_pencerem.show()
        print("tıkladık")

Adım 4 : Son olarak çalışma klasörü içerisine main.py adlı bir dosya oluşturarak içeriğini aşağıdaki şekilde düzenleyelim.

Python:
from PyQt5.QtWidgets import  QApplication
import sys
from ana_pen_code_ui import AnaPencere

# bir uygulama oluşturmak için QApplication sınıfından (sys.argv) ile bir uygulama nesnesi oluşturuyoruz.
uygulama = QApplication(sys.argv)
# artık bir uygulmamaız var.
# yazdığımız AnaPencere sınıfını örnekleyerek pencere nesnemizi oluşturuyoruz.
pencere = AnaPencere()
# artık birde penceremiz var.

pencere.show()   # penecereyi göster.
sys.exit(uygulama.exec_())  # pencerenin X butonuna basılır ise uygulamayı sonlandır.

Ve sonuç :

1617463728445.png


Birbiri ile ilişkili iki adet penceremiz ve bir adet uygulamamız oldu. Hangi pencere ne zaman açılacak ne zaman kapanacak isteğe/ihtiyaca göre farklı şekillerde tasarlanabilir. Ayrıca acemice de olsa moduler çalışmayı naçizane örneklemiş olduk...

Projenin dosyaları ektedir.
 

Ekler

  • Pencere olusturma 2.zip
    9.1 KB · Görüntüleme: 54
Top