PySide2 Dersleri etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
PySide2 Dersleri etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

11 Kasım 2018 Pazar

PySide2 Qt Designer ile Matplotlib Kullanımı

PySide2 Qt Designer ile Matplotlib Kullanımı


Algoritma geliştirirken veya test ederken bir arayüz hazırlayarak onun üzerinde çalışmanın işleri kolaylaştırdığını, zaman kazandırdığını ve sonuçları daha iyi yorumlama fırsatı sunduğunu düşünüyorum. Qt arayüz hazırlamak için çok iyi bir programdır ve C++ programlama dili ile kullanılmaktadır. Python son yıllarda kullanım alanı çok hızlı bir şekilde genişleyen, öğrenmesi ve kod yazması kolay olan veri bilimi, yapay zeka vb. bir çok alanda kullanılan bir programlama dilidir. Hem Python programlama dilinin nimetlerinden yararlanmak hem de Qt ile arayüz geliştirmek istediğimizde yakın zamana kadar karşımıza sadece PyQt çıkmaktaydı, artık 2. bir seçeneğimiz var PySide2. Qt'nin resmi olarak geliştirdiği "Qt for Python : PySide2" yakın zamanda kullanıma sunuldu. PySide2 kurulum ve kullanımı için aşağıda linkleri verilen yazılarımı takip edebilirsiniz.
PySide2 Windows/Ubuntu Kurulumu
PySide2 ile Grafiksel Kullanıcı Arayüzü (GUI) Geliştirme


Bu yazıda Python programlama dilinde veri görselleştirme aşamasında en yaygın olarak kullanılan matplotlib paketinin Qt Designer ile tasarlanan PySide2 arayüzünde nasıl kullanılacağından bahsedeceğim. Matplotlib sadece Python 3 ile kullanılmaktadır. Aşağıdaki komutu çalıştırarak Matplotlib kurulumunu kolayca gerçekleştirebilirsiniz.




pip install matplotlib






PyQt5 ve Matplotlib kurulumuna ek olarak NumPy modülünü Matplotlib ile çizdirmek istediğimiz verileri dizi olarak tutmak için kurmanızı tavsiye ederim. Aşağıdaki komutu kullanarak kolayca kurulumu gerçekleştirebilirsiniz.




pip install numpy





İhtiyaç duyulan tüm modüllerin kurulumunu gerçekleştirmiş olduk. Qt Designer ile tasarım yapılan PySide2 arayüzünde matplotlib modülünün nasıl kullanılacağından bahsedeceğim.

1. Qt Designer ile Tasarım

Adım 1.1.
Qt Designer açılır. Qt Designer'ı, PySide2 kurulumunu yaptığınız Python klasöründe ../Python37/Lib/site-packages/PySide2 bulabilirsiniz.


Adım 1.2.
Qt Designer açıldığında daha önce hazırladığınız bir tasarımı açabilmenizi ya da yeni bir tasarım oluşturmanızı sağlamak amacıyla bir pencere çıkmaktadır. Burada temel olarak Dialog, Main Window ve Widget seçenekleri mevcut. Dialog kullanıcıdan bir seçenek seçmesini isteyen ya da kullanıcıyı bilgilendiren pencerelerdir. Main Window'da Widget penceresinden farklı olarak Menu (menubar) oluşturabilir ve arayüzün en alt bölümünde statusbar olarak adlandırılan bölümde kullanıcıya bilgilendirme mesajları sunabilirsiniz. Bu pencereden yeni bir tasarım için Widget seçiyoruz. Siz farklı bir tercihte bulunabilirsiniz.


Adım 1.3.
Tasarlamak istediğimiz arayüzün ekran görüntüsünü aşağıda bulabilirsiniz. Bir tane buton ve bir tane grafikten oluşan, butona basınca grafiği güncelleyen basit bir arayüz. Tasarımın detaylarını yazarak anlatmak çok zor olduğundan yazının sonuna bir video koyacağım oradan bakabilirsiniz.


Adım 1.4.
Push Button ve Widget nesneleri sürükle-bırak yöntemiyle arayüze bırakılır.


Adım 1.5.
Widget üzerinde matplotlib ile üreteceğimiz grafikleri göstereceğiz. Bunun için fare (mouse) Widget'ın üzerindeyken sağ tıklanır ve açılan seçeneklerden Promote to ... seçilir.


Adım 1.6.
Promote to ... seçildikten sonra aşağıda ekran görüntüsünde gösterildiği gibi yeni bir pencere açılacaktır. Bu pencerede Promoted class name: yazan bölüme matplotlib kısaltması olan Mpl ön eki kullanılarak MplWidget yazılır. Siz istediğiniz ismi verebilirsiniz. Buraya yazdığınızda Header file: bölümü otomatik sizin yazdığınız isme göre dolacaktır. Sonra Add butonuna basılır.


Yukarıda bahsedilen adımlar tamamlandıktan sonra Promote butonuna basılır.


Not.
Yukarıda bahsedilen adımlara ek olarak arayüzde bulunan (Promote işlemi yapılan) Widget'ın nesne adı (objectName) Promoted class name değişkeni ile aynı isim yapılır.


Adım 1.7.
Son olarak yapmış olduğumuz tasarımı Ctrl + S tuş kombinasyonu ile .ui uzantılı olarak kaydediyoruz. Bu işlemle birlikte tasarım aşamasında yapılacaklar bitti. Şimdi Python kodlarıyla tasarlamış olduğumuz arayüzü kullanma aşamasına geçebiliriz.

2. Python ile Qt Designer Tasarımını Kullanma


Projemizde toplam 2 tane dosya olacak :
  • main.py : Qt designer'da tasarladığımız arayüzü yükleyeceğimiz ve üzerinde işlemler yapacağımız ana Python dosyamız.
  • qt_designer.ui : Qt designer'da tasarımı yapılan arayüz dosyası.


Burada bir önceki yazımda PyQt5 için yapmış olduğumuz arayüzün aynısını PySide2 için yapacağız.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# ------------------ PySide2 - Qt Designer - Matplotlib ------------------
from PySide2.QtWidgets import*
from PySide2.QtUiTools import QUiLoader
from PySide2.QtCore import QFile

from matplotlib.backends.backend_qt5agg import (
        FigureCanvas, NavigationToolbar2QT as NavigationToolbar)

from matplotlib.figure import Figure

import numpy as np
import random

# ------------------ MplWidget ------------------
class MplWidget(QWidget):
    
    def __init__(self, parent = None):
        
        QWidget.__init__(self, parent)
        
        self.canvas = FigureCanvas(Figure())
        
        vertical_layout = QVBoxLayout()
        vertical_layout.addWidget(self.canvas)
        vertical_layout.addWidget(NavigationToolbar(self.canvas, self))
        
        self.canvas.axes = self.canvas.figure.add_subplot(111)
        self.setLayout(vertical_layout)    

# ------------------ MainWidget ------------------
class MainWidget(QWidget):
    
    def __init__(self):
        
        QWidget.__init__(self)

        designer_file = QFile("qt_designer.ui")
        designer_file.open(QFile.ReadOnly)

        loader = QUiLoader()
        loader.registerCustomWidget(MplWidget)
        self.ui = loader.load(designer_file, self)

        designer_file.close()

        self.ui.pushButton_generate_random_signal.clicked.connect(self.update_graph)

        self.setWindowTitle("PySide2 & Matplotlib Example GUI")

        grid_layout = QGridLayout()
        grid_layout.addWidget(self.ui)
        self.setLayout(grid_layout)


    def update_graph(self):
        
        fs = 500
        f = random.randint(1, 100)
        ts = 1/fs
        length_of_signal = 100
        t = np.linspace(0,1,length_of_signal)
        
        cosinus_signal = np.cos(2*np.pi*f*t)
        sinus_signal = np.sin(2*np.pi*f*t)

        self.ui.MplWidget.canvas.axes.clear()
        self.ui.MplWidget.canvas.axes.plot(t, cosinus_signal)
        self.ui.MplWidget.canvas.axes.plot(t, sinus_signal)
        self.ui.MplWidget.canvas.axes.legend(('cosinus', 'sinus'),loc='upper right')
        self.ui.MplWidget.canvas.axes.set_title('Cosinus - Sinus Signals')
        self.ui.MplWidget.canvas.draw()
        

app = QApplication([])
window = MainWidget()
window.show()
app.exec_()

Adım 2.1.
Yukarıda yer alan kodları 4 parça halinde anlatacağım. İlk bölümde (2-12 nolu satırlar) ihtiyaç duyulan paketler koda dahil edilir.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# ------------------ PySide2 - Qt Designer - Matplotlib ------------------
from PySide2.QtWidgets import*
from PySide2.QtUiTools import QUiLoader
from PySide2.QtCore import QFile

from matplotlib.backends.backend_qt5agg import (
        FigureCanvas, NavigationToolbar2QT as NavigationToolbar)

from matplotlib.figure import Figure

import numpy as np
import random

2 nolu satırda QtWidgets sınıfına ait tüm bileşenler kod içerisinde kullanmak için eklenir.
3 ve 4 nolu satırlarda Designer tasarım dosyasını yüklemek için kullandığımız QUiLoader ve QFile modüllerini kodumuza ekliyoruz.
6 nolu satırda Matplotlib modülünden FigureCanvas kodumuza eklenir.
Matplotlib 3 farklı katmandan oluşur ve en alt katmanda Backend, bir üst katmanda Artist ve en üst katmanda Scripting katmanı bulunmaktadır. Matplotlib modlünün yapısı hakkında detaylı bilgiye buradan ulaşabilirsiniz.
Backend katmanında bulunan FigureCanvas resim çizmek için ihtiyaç duyduğumuz kağıt (tuval) gibi düşünülebilir. FigureCanvas Matplotlib sınıfı olmasının yanında aynı zamanda bir QWidget sınıfıdır.
Artist katmanında Matplotlib de gördüğümüz başlık, grafik, x-y ekseni, etiketler vb. bileşenler yer almaktadır.
Script (pyplot) katmanı Matplotlib modülünün kolay kullanımını sağlayan en üst katmandır.
7 nolu satırda grafik üzerinde işlem yapabilmek için Matplotlib modülünden NavigationToolBar2QT koda dahil edilir.
9 nolu satırda Matplotlib modülünden Figure sınıfı kodumuza eklenir.
Aslında Matplotlib içerisinde PySide2 için tanımlanmış fonksiyonlar, sınıflar yok. Yukarıda yer alan kodlarda gördüğünüz gibi PyQt5 için var olan sınıf ve fonksiyonlar PySide2 için kullanılacaktır.
11 nolu satırda NumPy paketi matematiksel işlemler ve dizi işlemlerinde kullanmak için eklenmiştir.
12 nolu satırda Python kurulumu ile birlikte gelen random paketi rastgele sayı üretmek için koda eklenmiştir.

Adım 2.2.
İkinci bölümde (14-28 nolu satırlar) MplWidget sınıfı tanımlanmıştır. Qt designer'da Promote işlemi yapılan widget ile aynı ismi taşıdığına dikkat ediniz. Burada Matplotlib'in widget'ta kullanılmasını sağlayan işlemler yapılır.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# ------------------ MplWidget ------------------
class MplWidget(QWidget):
    
    def __init__(self, parent = None):
        
        QWidget.__init__(self, parent)
        
        self.canvas = FigureCanvas(Figure())
        
        vertical_layout = QVBoxLayout()
        vertical_layout.addWidget(self.canvas)
        vertical_layout.addWidget(NavigationToolbar(self.canvas, self))

        self.canvas.axes = self.canvas.figure.add_subplot(111)
        self.setLayout(vertical_layout)

15-19 nolu satırlar her sınıfta bulunması gereken daha önce açıkladığım kısımlar olduğu için burada tekrar etmeyeceğim.
21 nolu satırda FigureCanvas sınıfından yeni bir nesne tanımlanmaktadır ve nesne adı (object name) "canvas" olarak tanımlanmıştır ve sınıf dışında bu etikete ulaşmamız gerekeceğinden bu parçacık self ifadesine atanmıştır.
23 nolu satırda dikey yerleşim düzeni ( QVBoxLayout ) tanımlıyoruz ve 24 nolu satırda addWidget fonksiyonunu kullanarak oluşturduğumuz FigureCanvas nesnesini bu dikey yerleşim planı içerisine ekliyoruz. 25 nolu satırda ise matplotlib paketinde yer alan NavigationToolBar2QT dikey yerleşim planı içerisine eklenir. Qt'de dikey yerleşim düzeninden ( QVBoxLayout ) farklı olarak Yatay yerleşim düzeni ( QHBoxLayout ) ve Izgara yerleşim düzeni ( QGridLayout ) bulunmaktadır.
27 nolu satırda oluşturduğumuz tuvale (FigureCanvas) yeni bir Axes tanımlıyoruz. Bu işlem için add_subplot fonksiyonunu kullanıyoruz.
28 nolu satırda oluşturduğumuz dikey yerleşim düzenini sınıfımızın (oluşturacağımız arayüzün) yerleşim düzeni olmasını sağlamak için setLayout fonksiyonuyla tanımlıyoruz. Bu satırla birlikte MplWidget sınıfına ait kodlarının açıklaması bitmiştir.

Adım 2.3.
Üçüncü bölümde (30-71 nolu satırlar) MainWidget ana sınıf tanımlanmıştır. Burada Qt Designer ile yapılan tasarım; içerisinde yer alan bileşenlere ulaşmak, üzerinde işlem yapabilmek için yüklenecektir.

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# ------------------ MainWidget ------------------
class MainWidget(QWidget):
    
    def __init__(self):
        
        QWidget.__init__(self)

        designer_file = QFile("qt_designer.ui")
        designer_file.open(QFile.ReadOnly)

        loader = QUiLoader()
        loader.registerCustomWidget(MplWidget)
        self.ui = loader.load(designer_file, self)

        designer_file.close()

        self.ui.pushButton_generate_random_signal.clicked.connect(self.update_graph)

        self.setWindowTitle("PySide2 & Matplotlib Example GUI")

        grid_layout = QGridLayout()
        grid_layout.addWidget(self.ui)
        self.setLayout(grid_layout)


    def update_graph(self):
        
        fs = 500
        f = random.randint(1, 100)
        ts = 1/fs
        length_of_signal = 100
        t = np.linspace(0,1,length_of_signal)
        
        cosinus_signal = np.cos(2*np.pi*f*t)
        sinus_signal = np.sin(2*np.pi*f*t)

        self.ui.MplWidget.canvas.axes.clear()
        self.ui.MplWidget.canvas.axes.plot(t, cosinus_signal)
        self.ui.MplWidget.canvas.axes.plot(t, sinus_signal)
        self.ui.MplWidget.canvas.axes.legend(('cosinus', 'sinus'),loc='upper right')
        self.ui.MplWidget.canvas.axes.set_title('Cosinus - Sinus Signals')
        self.ui.MplWidget.canvas.draw()

31-35 nolu satırlar her sınıfta bulunması gereken daha önce açıkladığım kısımlar olduğu için burada tekrar etmeyeceğim.
37 ve 38 nolu satırlarda tasarım dosyasını (qt_designer.ui) okuyoruz.
40 nolu satırda QUiLoader sınıfından bir nesne tanımlıyoruz.
41 nolu satırda registerCustomWidget fonksiyonuyla Promote işlemi yaptığımız ve yukarıda MplWidget sınıfıyla tanımladığımız widget'ı kullanabilmemiz için bu fonksiyonu kullanmamız gerekir.
42 nolu satırda load fonskiyonuyla tasarım yüklenir ve self.ui değişkenine atanır. Tasarımla oluşturulan parçacıklara bu değişkeni kullanarak ulaşacağız.
44 nolu satırda yüklenen tasarım dosyası kapanır.
46 nolu satırda Qt Designer'da tanımladığımız butonun clicked sinyaline update_graph fonksiyonunu (slot) bağlıyoruz. Signal-slot bağlantısı için önceki yazıma bakabilirsiniz.
48 nolu satırda arayüz penceresine setWindowTitle fonksiyonu ile isim veriyoruz.
50-52 nolu satırlar hazırladığımız arayüzü farklı boyutlarda kullanmamızı sağlayacaktır.


55-71 nolu satırlar arası butona bağlanan update_graph fonksiyonu (slot) yazılmıştır. Kullanıcı butona her bastığında kodumuz bu fonksiyonu çalıştıracaktır.
57-64 satırlar arası, NumPy ve random paketlerindeki fonksiyonlar kullanılarak rastgele frekanslarda sinus ve cosinus fonksiyonları üretilmektedir.
66 nolu satırda grafiğe yeni bir çizim yapmadan önce önceki çizimler silinir. Bu işlemi yapmazsak grafikleri üst üste çizer.
67-68 nolu satırlarda üretilen cosinus ve sinus fonksiyonları çizdirilmektedir.
69 nolu satırda çizdirdiğimiz grafikleri ayırt etmek için legend eklenir.
70 nolu satırda grafiğe başlık eklenir.
71 nolu satırda grafiğimiz çizdirilir.

Adım 2.4.
Son bölümde (74-77 nolu satırlar) arayüzün gösterilmesi ve çalıştırılması işlemleri yapılır.

74
75
76
77
app = QApplication([])
window = MainWidget()
window.show()
app.exec_()

74 nolu satırda QApplication sınıfından app adında bir nesne tanımlıyoruz.
75 nolu satırda MainWidget adında tanımladığımız sınıftan window adında bir nesne oluşturuyoruz.
76 nolu satırda show() fonksiyonunu kullanarak arayüz için oluşturduğumuz pencereyi gösteriyoruz
77 nolu satırda QApplication sınıfının exec_() fonksiyonu ile sonsuz bir döngü oluşturulur. Bu ifade ile kullanıcının arayüzü kullanarak fare ve klavye ile yapmış olduğu tüm işlemler yakalanarak komutlar yerine getirilir.


Qt Designer ile tasarlanan arayüzde Matplotlib paketini kullanarak nasıl grafik çizdireceğimizi öğrenmiş olduk. Değinmediğimiz birçok özellik olabilir, ancak bunu bir başlagıç olarak kabul ederek daha iyi daha güzel arayüzleri kendi çalışmalarınız için hazırlayabilirsiniz.


2 Eylül 2018 Pazar

PySide2 ile Grafiksel Kullanıcı Arayüzü (GUI) Geliştirme

PySide2 ile Grafiksel Kullanıcı Arayüzü (GUI) Geliştirme


PySide2 hakkında detaylı açıklamaların yer aldığı ve PySide2 Kurulumunun anlatıldığı önceki yazımı aşağıdaki linkte bulabilirsiniz.

Qt for Python : PySide2 Kurulumu

Burada PySide2 ile ilk uygulamamızı geliştireceğiz. Daha önce PyQt5 ile geliştirmiş olduğumuz arayüzün aynısını geliştireceğiz.


1. Kod Yazarak Arayüz Geliştirme

Geliştireceğimiz arayüz aşağıdaki ekran görüntüsünde gösterilmiştir. Bu arayüz bir etiket (QLabel) iki tane düğmeden (QPushButton) oluşmaktadır. Etikette "Qt for Python" yazmaktadır. Temizle düğmesi ile etikette yazan yazı silinmektedir. Göster düğmesi ile etikete yeniden "Qt for Python" yazılmaktadır. Sinyal-slot yapısından PyQt5 ile ilk uygulamamızda bahsettiğimden burada bahsetme gereği duymadım. İsteyenler yukarıda linkini verdiğim PyQt5 ile arayüz geliştirme yazısını inceleyebilirler.


Bu arayüzü elde etmek için yazacağımız kod aşağıda belirtilmiştir.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import sys
from PySide2.QtCore import Qt
#from PySide2.QtWidgets import (QApplication, QWidget, QPushButton, QLabel, QVBoxLayout)
from PySide2.QtWidgets import*

class MyWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        self.label_text = QLabel("Qt for Python")
        self.label_text.setAlignment(Qt.AlignCenter)
        self.label_text.setStyleSheet("color: rgb(0,0,255);font-weight: bold; font-size: 16pt")

        pushButton_clear = QPushButton("Temizle")
        pushButton_clear.setMinimumHeight(40)
        pushButton_clear.setStyleSheet("font-weight: bold; font-size: 16pt")
        pushButton_show = QPushButton("Göster")
        pushButton_show.setMinimumHeight(40)
        pushButton_show.setStyleSheet("font-weight: bold; font-size: 16pt")

        vertical_layout = QVBoxLayout()
        vertical_layout.addWidget(self.label_text)
        vertical_layout.addWidget(pushButton_clear)
        vertical_layout.addWidget(pushButton_show)

        self.setLayout(vertical_layout)
        self.setWindowTitle("Qt for Python : PySide2")

        pushButton_clear.clicked.connect(self.clear_text)
        pushButton_show.clicked.connect(self.show_text)
        

    def clear_text(self):
        self.label_text.clear()

    def show_text(self):
        self.label_text.setText("Qt for Python")
        

if __name__ == "__main__":

    app = QApplication(sys.argv)

    widget = MyWidget()
    widget.resize(400, 300)
    widget.show()
    sys.exit(app.exec_())

Şimdi bu kodları adım adım açıklayalım.

1
2
3
4
import sys
from PySide2.QtCore import Qt
#from PySide2.QtWidgets import (QApplication, QWidget, QPushButton, QLabel, QVBoxLayout)
from PySide2.QtWidgets import*

1 nolu satırda sys modülü eklenir. 2 nolu satırda QtCore modülünden Qt 11 nolu satırda kullanmak için eklenir. 3 ve 4 nolu satırlar birbiri yerine kullanılabilir. İstersek 4 nolu satırda olduğu gibi QtWidgets modülüne ait tüm bileşenler kod içerisinde kullanmak için eklenir. İsterseniz 3 nolu satırda belirtildiği gibi sadece ihtiyaç duyulan bileşenleri kod içerisine ekleyebilirsiniz.

6
7
8
class MyWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)

6 nolu satırda QWidget sınıfından ürettiğimiz "MyWidget" adında sınıfı tanımlıyoruz. Burada QWidget yerine QDialog ya da QMainWindow tipinde bir sınıf oluşturabilirdik. Her sınıfın __init__() fonksiyonu vardır ve sınıf çağrıldığında ilk olarak bu fonksiyon çalıştırılır. self ifadesi bir sınıfta tanımlanan değişkenlerin, fonksiyonların sınıf dışından çağrılabilmesi için o sınıfa ait bir fonksiyon, değişken olduğunu belirtmek için kullanılır. C++ programlama dilinde kullanılan this ifadesi ile aynı kullanıma sahiptir. 7 nolu satırda sınıfımıza ait __init__() fonksiyonunu, 8 nolu satırda ise Miras aldığımız QWidget sınıfının __init__() fonksiyonunu tanımlıyoruz.

10
11
12
        self.label_text = QLabel("Qt for Python")
        self.label_text.setAlignment(Qt.AlignCenter)
        self.label_text.setStyleSheet("color: rgb(0,0,255);font-weight: bold; font-size: 16pt")

10 nolu satırda QLabel etiket parçacığı (widget) "Qt for Python" yazısını içerecek şekilde oluşturulur. Nesne adı (object name) "label_text" olarak tanımlanmıştır ve sınıf dışında (slot tanımlamalarında) bu etikete ulaşmamız gerekeceğinden bu parçacık self ifadesiyle tanımlanmıştır.
11 nolu satırda etiket içerisinde yazan yazının hizalaması ortalanmıştır. Bu hizalamayı setAlignment fonksiyonu sağlamaktadır.
12 nolu satırda etikette yazan yazının rengini, font büyüklüğünü ve font kalınlığını setStyleSheet fonksiyonunu CSS tanımlamaları kullanarak ayarlıyoruz.


14
15
16
17
18
19
        pushButton_clear = QPushButton("Temizle")
        pushButton_clear.setMinimumHeight(40)
        pushButton_clear.setStyleSheet("font-weight: bold; font-size: 16pt")
        pushButton_show = QPushButton("Göster")
        pushButton_show.setMinimumHeight(40)
        pushButton_show.setStyleSheet("font-weight: bold; font-size: 16pt")

14 nolu satırda üzerinde "Temizle" yazan QPushButton (buton, düğme, tuş) parçacığı tanımlıyoruz. Bu düğmenin minimum yüksekliğini 40 piksel olarak 15 nolu satırda setMinimumHeight fonksiyonunu kullanarak tanımlıyoruz.
16 nolu satırda daha önce etiket için yaptığımız gibi setStyleSheet fonksiyonunu kullanarak düğme üzerinde yazan yazının font özelliklerinde daha güzel görünmesini sağlayacak değişiklikler yapıyoruz. Bu düğmemizin adını "pushButton_clear" olarak tanımlıyoruz. Ben hangi parçacık olduğunu belirten (pushButton) ve ne işe yarayacağını belirten (temizle, clear) kelimeleri birleştirerek isimlendirme yapıyorum. Böylece kod içerisinde hangi tipte bir düğme olduğunu ve ne işe yaradığını anlamak kolay oluyor ve kodun anlaşılabilirliğini arttırıyor. Burada etiketten farklı olarak oluşturduğumuz düğmeyi self'e atamadık çünkü sınıf dışında ihtiyacımız olmayacak eğer ihtiyaç duyarsak self olarak tanımlamalıyız.
17, 18 ve 19 nolu satırlar önceki satırların 2. düğme olan "Göster" düğmesini oluşturmamıza ve aynı işlemleri onun üzerinde yapmamızı sağlamaktadır.


21
22
23
24
        vertical_layout = QVBoxLayout()
        vertical_layout.addWidget(self.label_text)
        vertical_layout.addWidget(pushButton_clear)
        vertical_layout.addWidget(pushButton_show)

21 nolu satırda dikey yerleşim düzeni ( QVBoxLayout ) tanımlıyoruz ve 22, 23, 24 nolu satırlarda addWidget fonksiyonunu kullanarak sırasıyla oluşturduğumuz etiket ve düğmeleri bu dikey yerleşim planı içerisine ekliyoruz. Tasarımınıza göre Yatay yerleşim düzeni ( QHBoxLayout ) veya ızgara yerleşim düzeni ( QGridLayout ) kullanabilirsiniz.

26
27
        self.setLayout(vertical_layout)
        self.setWindowTitle("Qt for Python : PySide2")

26 nolu satırda oluşturduğumuz dikey yerleşim düzenini sınıfımızın (oluşturacağımız arayüzün) yerleşim düzeni olmasını sağlamak için setLayout fonksiyonuyla tanımlıyoruz.
27 nolu satırda arayüzün gösterileceği pencerenin adının "Qt for Python : PySide2" olmasını setWindowTitle fonksiyonunu kullanarak sağlıyoruz.

29
30
        pushButton_clear.clicked.connect(self.clear_text)
        pushButton_show.clicked.connect(self.show_text)

29 ve 30 nolu satırlar, sinyaller ile fonksiyonları (slotları) birbirine connect metodunu kullanarak bağladığımız satırlardır. "Temizle" düğmesinin clicked sinyalini "clear_text" fonksiyonuyla birbirine bağladık ve "Temizle" düğmesine tıklandığında "clear_text" fonksiyonu çağrılacaktır. "Göster" düğmesinin clicked sinyalini de "show_text" fonksiyonuna bağladık. Kod yazarken türkçe karakter kullanamadığımızdan anlaşılabilir olması için ingilizce değişken ve fonksiyon adı kullanmayı tercih ediyorum.

33
34
    def clear_text(self):
        self.label_text.clear()

33 nolu satırda "Temizle" düğmesinin tıklama sinyaline bağlanan "clear_text()" slotunu (fonksiyonunu) tanımlıyoruz. Değişken olarak self değişkenini almaktadır. İşlem olarak QLabel sınıfının clear() fonksiyonu ile etiket içerisinde yazan yazı temizlenir.

36
37
    def show_text(self):
        self.label_text.setText("Qt for Python")

36 ve 37 nolu satırlarda "Göster" düğmesinin "show_text()" slotu tanımlanmaktadır. Bir etikete yazı yazmak için setText() fonksiyonu kullanılmaktadır ve bu düğmeye tıklandığında "Qt for Python" yazısı yazacaktır. Bu düğmenin yaptığı işi gözlemlemek için öncelikle etikette yazan yazı silinmelidir.


40
41
42
43
44
45
46
47
if __name__ == "__main__":

    app = QApplication(sys.argv)

    widget = MyWidget()
    widget.resize(400, 300)
    widget.show()
    sys.exit(app.exec_())

Sınıf ve slot tanımlamalarından sonra 42 nolu satırda QApplication sınıfından "app" adında bir nesne tanımlıyoruz. 44 nolu satırda "MyWidget" adında tanımladığımız sınıftan "widget" adında bir nesne oluşturuyoruz. 45 nolu satırda kodu çalıştırdığımızda ekrana gelecek pencerenin boyutlarını resize() fonksiyonu ile ayarlıyoruz. widget nesnesinin show() fonksiyonunu kullanarak arayüz için oluşturduğumuz pencereyi gösteriyoruz (46 nolu satır). 47 nolu satırda QApplication sınıfının exec_() fonksiyonu ile sonsuz bir döngü oluşturulur. Bu ifade ile kullanıcının arayüzü kullanarak fare ve klavye ile yapmış olduğu tüm işlemler yakalanarak komutlar yerine getirilir. Pencere kapatılana kadar döngü devam eder.
Böylece kod yazarak PySide2 ile kullanıcı arayüzü geliştirmiş olduk.

2. Qt Designer ile Arayüz Geliştirme

Kod yazarak geliştirmiş olduğumuz arayüzün aynısını Qt Designer ile de gerçekleştirebiliriz. Qt Designer'ı ..\Python37\Lib\site-packages\PySide2 klasöründe bulabilirsiniz. Yani Python kurulum dosyalarının yer aldığı ..\Lib\site-packages\PySide2 klasöründe. Qt Designer ile PySide2 kullanılarak arayüz geliştirmenin nasıl yapıldığını öğrenmek için aşağıdaki videoyu izleyebilirsiniz.


Designer ile yapmış olduğumuz tasarımı kullanabilmek için aşağıdaki kodlara ihtiyacımız var.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import sys
from PySide2.QtWidgets import QApplication, QWidget
from PySide2.QtUiTools import QUiLoader
from PySide2.QtCore import QFile

class MyWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        designer_file = QFile("example_widget.ui")
        designer_file.open(QFile.ReadOnly)

        loader = QUiLoader()
        self.ui = loader.load(designer_file, self)

        designer_file.close()

        self.ui.pushButton_clear.clicked.connect(self.clear_text)
        self.ui.pushButton_show.clicked.connect(self.show_text)

        self.setWindowTitle("Qt for Python : PySide2")


    def clear_text(self):
        self.ui.label_text.clear()


    def show_text(self):
        self.ui.label_text.setText("Qt for Python")


if __name__ == "__main__":

    app = QApplication(sys.argv)

    widget = MyWidget()
    widget.show()

    sys.exit(app.exec_())

Burada kod yazarak geliştirdiğimiz arayüzden farklı olarak yazılan kısımları açıklayalım. 3 ve 4 nolu satırlarda Designer tasarım dosyasını yüklemek için kullandığımız QUiLoader ve QFile modüllerini kodumuza ekliyoruz.
10 ve 11 nolu satırlarda tasarım dosyasını okuyoruz. 14 nolu satırda tasarımımızı 13 nolu satırda tanımlanan loader nesnesi ve load() fonksiyonunu kullanarak yüklüyoruz.
16 nolu satırda, self.ui 'ye atadığımız tasarım dosyasını kapatıyoruz. Kodun geriye kalan kısımları ilk bölümle aynı olduğu için ilk bölümdeki açıklamalara bakabilirsiniz.