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
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.
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.
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.
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.
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.
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.
Hiç yorum yok:
Yorum Gönder