Qt for Python etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Qt for Python etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

6 Nisan 2020 Pazartesi

Design2Py Converter v1.5

Design2Py Converter v1.5



PyQt5 ile arayüz geliştirirken tasarım yapmak için aşağıdaki şemada görüldüğü gibi 2 yöntem mevcuttur:

1) Kod ile tasarım yapmak,
2) Qt designer ile tasarım yapmak


Genellikle zaman kazandırdığı ve kolay olduğu için Qt Designer ile tasarım yapmayı tercih ediyorum. Qt Designer ile tasarım yapıldığında bu tasarımın Python ile kullanılması gerekmektedir. Bu aşamada da 2 farklı yöntem mevcuttur:

1) Pyuic5 ile hazırlanan tasarım Python kodlarına dönüştürülür.
2) loadUi fonksiyonu ile tasarım Python tarafından çağrılır.

loadUi fonksiyonu kullanıldığında arayüz elemanları proje geliştirirken okunamadığı için kod tamamlama özelliği çalışmıyor. Bu özellik çalışmadığında hem arayüz elemanları nesne adlarıyla çağrılırken hem de arayüz elemanlarının sahip olduğu özellikleri (fonksiyonları) kullanırken zorlanıyorsunuz. Bu sebeple hazırlamış olduğum tasarımı Pyuic5 ile Python kodlarına dönüştürmeyi tercih ediyorum. Pyuic5 dönüştürücüsünün nasıl kullanıldığını Ücretsiz PyQt5 Dersleri eğitim serisinde bulabilirsiniz. Biraz zahmetli, hataya açık ve arayüz geliştirirken vakit alan bir işlem olduğu için bu işlemleri daha kolay yapabilmek adına Design2Py Converter programını geliştirdim. YouTube kanalımda PyQt5 derslerini anlatırken sıklıkla kullandım ve mail aracılığı ile isteyenlere ücretsiz olarak verdim. (Bu yazının yazıldığı tarih itibariyle benden 109 kişi programı istedi. Eğer onlarda verdiğim linki başkalarıyla paylaştıysa gerçek kullanıcı sayısı daha fazla olabilir.) Design2Py Converter v1.3 hakkında detaylı bilgilere buradan ulaşabilirsiniz.

Design2Py Converter v1.3'te Karşılaşılan Hatalar

Programı farklı işletim sistemlerinde çok sayıda kişi kullandı ve geri bildirim olarak aşağıdaki hataları bildirdiler:

1) Farklı PyQt5 versiyonlarında Pyuic5'in farklı yapıda olmasından dolayı bir versiyonda başarılı bir şekilde dönüşüm yaparken (PyQt 5.6 - pyuic5.bat) bir başka versiyonda (PyQt 5.11.3 - pyuic5.exe) dönüşüm yapmaması.
2) Pyuic5 veya Pyrcc5 in bulunduğu klasör yolunu bulmak için ortam değişkenlerine erişmeye çalışıyordum ve bu sebeple programın kapanması.

Yeni özelliklerin olduğu ve bahsedilen hataların olmadığı v1.5 hazırlandı.

Design2Py Converter v1.5'te Yenilikler

1. Dil Desteği

Design2Py Converter v1.5 Türkçe ve İngilizce olmak üzere 2 farklı dilde çalışabilmektedir. Dil tercihi menüden değiştirilebilmektedir.



2. Ayarları Kaydetme-Yükleme Özelliği

Kullanım kolaylığı için getirilen bir özelliktir. Programı kapatmadan önce mevcut ayarlarını (dil tercihi, seçilen sekme (sayfa) ve dosya yolları) kayıt ederseniz ve programı daha sonra açtığınızda kaldığınız yerden devam edebilmek için kaydetmiş olduğunuz ayarları yükleyebilirsiniz. Böylelikle her seferinde dosya yollarını ayarlamak zorunda kalmazsınız.



Ayrıca Programın bulunduğu klasör içerisinde formata uygun (program tarafından oluşturulmuş) init.json adında ayarlar dosyası varsa, Design2Py Converter bu dosyada yer alan ayarlara göre açılacaktır. Bu özellik sayesinde kaydetmiş olduğunuz ayarları tekrar yüklemenize ihtiyaç duymayacaksınız.

3. Yardım Menüsünde Yapılan Değişiklikler

Yardım menüsünde 2 ufak değişiklik yapılmıştır. Daha önce YouTube kanalıma yönlendiren link zaten PyQt5 Dersleri ile YouTube kanalına gidilebildiği için Blog sayfama yönlendirilmiştir ve adı Yapay Zeka Labs Blog olarak değiştirilmiştir. İkinci olarak Sürüm Notları seçeneği ile program ve versiyon hakkında detaylı bilgilere ulaşılması adına bu sayfaya yönlendirme sağlanmıştır.



4. Yapay Zeka Labs Sekmesi

Giriş sekmesinde bulunan Yapay Zeka Labs logosuna tıkladığınızda Yapay Zeka Labs YouTube kanalım açılacaktır.


5. ui-2-py Sekmesi

Programın farklı PyQt5 versiyonlarında Pyuic5'in farklı yapıda olmasından dolayı bir versiyonda başarılı bir şekilde dönüşüm yaparken (PyQt 5.6 - pyuic5.bat) bir başka versiyonda (PyQt 5.11.3 - pyuic5.exe) dönüşüm yapmaması en büyük problemdi ve bu problemden kurtulmak için Pyuic5 bileşeninin kullanımını iptal ettim. Dönüşüm işleri programın içinde gerçekleşmektedir. Bu sekmede kullanıcının yapması gereken tek şey dönüştürmek istediği tasarımı Tasarımı (.ui) Seç butonuna basarak seçmesidir. Önceki versiyonda (v1.3) Python kodlarına dönüştürülen tasarım mevcut tasarım ile aynı klasöre ve tasarım adının sonuna _python eklenerek kaydediliyordu. Kullanıcıya kayıt isminde ve klasör yolunda değişiklik yapma hakkı tanıdım. İsterse Kayıt Yoluna Gözat tuşuna basarak değişiklik yapabilir. Son olarak dönüşüm işlemini gerçekleştirmek için kullanıcının Dönüştür ui -> py tuşuna basması gerekiyor.

Buna ek olarak Pyuic5'in hangi klasörde olduğunu bulmak için "Ortam Değişkenlerine" erişmeye çalışmamdan kaynaklanan sorunlardan da kurtulmuş oldum.



6. qrc-2-py Sekmesi

"Ortam Değişkenlerine" erişerek Pyuic5 ve Pyrcc5 in bulunduğu klasör yolunu kullanıcıyı yormadan bulmam güzel bir özellikti ancak farklı kullanıcılarda bahsettiğim gibi sorunlara yol açmıştı. Arayüz açılırken kayıtlı ayarlarla açılması ve mevcut ayarların kayıt edilmesi özelliklerini getirerek yine kullanıcıyı yormadan ihtiyaç duyulan klasör yolları otomatik bulunacaktır. Kullanıcının klasör yollarını değiştirmediği sürece sadece bir defa bilgisayarında Pyrcc5'in bulunduğu klasör yolunu bulması gerekecektir. Pyrcc5'e Gözat tuşuna basılarak Pyrcc5 seçildikten sonra Dosyayı (.qrc) Seç tuşuna basılarak Python kodlarına dönüştürülmek istenen Qt Kaynak Dosyası seçilmelidir. Son olarak Python kodlarını elde etmek için Dönüştür qrc->py tuşuna basılmalıdır.



Burada Python kodlarına dönüştürülen Qt kaynak dosyası mevcut Qt kaynak dosyası ile aynı klasöre aynı ismin sonuna _rc eklenerek kaydedilmektedir.

Design2Py Converter v1.5 İndirme Bağlantıları

İşletim Sistemi Design2Py Converter Yayınlanma Tarihi
Windows 7-10 v1.5.0 08.04.2020 - 19:34
Ubuntu 16.04 v1.5.0 08.04.2020 - 19:44
Ubuntu 18.04 v1.5.0 09.04.2020 - 00:50
MacOS High Sierra 10.13 v1.5.0 19.05.2020 - 13:40
Raspbian - -
Ubuntu Mate - -

Test Edilen PyQt5 Versiyonları

Aşağıdaki tabloda Design2Py Converter programının test edildiği ve herhangi bir sorunla karşılaşılmayan PyQt5 versiyonları gösterilmektedir. Benim tek başıma her işletim sistemi için ve her PyQt5 versiyonu için test etmek için vaktim olmadığından sizler de burada yer almayan PyQt5 versiyonları kullanıyorsanız, programın o versiyonlar için de durumunu yorum olarak bildirirseniz tabloyu o bilgiler ışığında güncelleyeceğim.

İşletim Sistemi Test Edilen PyQt5 Versiyonları
Windows 7-10 5.6.0 - 5.11.3 - 5.13.2
Ubuntu 16.04 5.11.3
Ubuntu 18.04 5.13.1
MacOS High Sierra 10.13 5.11.3
Raspbian -
Ubuntu Mate -


27 Aralık 2018 Perşembe

Qt'de Signal-Slot Kavramı

Qt Signal - Slot (İşaret - İşlev) Kavramı


Qt birden çok platformu destekleyen (cross-platform) masaüstü, gömülü sistem ve mobil ortamlar için grafiksel kullanıcı arayüzü geliştirmemizi sağlayan bir araçtır. Qt ile kullanıcı arayüzü geliştirmek için C++ programlama dili kullanılmaktadır. Qt'nin bana göre en önemli avantajı birçok işletim sisteminde (Windows, Linux, Mac) kullanılabiliyor olmasıdır (cross-platform özelliği). Bu özelliğe ek olarak ticari yazılımlar dışında hobi amaçlı yazılımlar için lisanslama sorunu yoktur. Ayrıca Qt ile arayüz geliştirmek Qt nin sunmuş olduğu sınıflar, fonksiyonlar ve signal-slot mekanizması sayesinde çok kolaydır. Diğer arayüz geliştirme ve programlama dillerinde olmayan signal-slot kavramı Qt de karşımıza çıkmaktadır. Bu yazıda
  • Signal-slot nedir ?
  • Signal-slot mekanizması nasıl çalışır ?
  • Öntanımlı (Default) işaretler (signal) nedir, nasıl kullanılır ?
  • Qt Designer ile signal-slot bağlantısı nasıl yapılır ?
  • Kod yazarak signal-slot bağlantısı nasıl yapılır ?
  • Kendimiz işaret (signal) tanımlayabilir miyiz ?
  • Signal-slot bağlantısı nasıl kaldırılır (iptal edilir)?
  • sorularına cevap bulacağız.


1. Signal - Slot Nedir ? Signal - Slot Mekanizması Nasıl Çalışır ?

Signal çok yabancı olmadığımız bir kelime Türkçeye de sinyal olarak geçmiştir. Slot kelimesinin ise yuva anlamı vardır. Aslında slot programlama dili açısından düşünüldüğünde fonksiyon olarak kullanılabilir. Fonksiyon da dilimizde yaygın olarak kullanılan bir kelime olmasına karşın Türkçe karşılığı işlev'dir. Signal-Slot yerine işaret-işlev diyebiliriz ancak bu kavram Qt'ye özgü bir kavram olduğu için signal-slot kavramından işaret-işlev olarak bahsedildiğinde kimse anlamayacaktır. Bu sebeple yazının geri kalan bölümünde signal-slot olarak orijinal hali ile kullanmayı planlıyorum.


Signal-slot kavramını yukarıda yer alan animasyon üzerinden anlatmaya çalışalım. Animasyonun sol üst köşesinde bir kullanıcı yer alıyor, sağ üst köşede ise bizim hazırlamış olduğumuz bir kullanıcı arayüzü olduğunu varsayalım. Kullanıcı, hazırlamış olduğumuz arayüz üzerinde bir eylemde bulunduğunda örneğin bir tuşa bastığında bir sinyal yayınlanır ve bu sinyal bir fonksiyona bağlı ise o fonksiyon çağrılır ve fonksiyon içerisinde yer alan işlem gerçekleştirilir. Arayüzü hazırlayan kişi arayüz elemanları ve fonksiyonlar arasında signal-slot bağlantıları yapar ve kullanıcı arayüz üzerinde bir işlem yaptığında ilgili fonksiyon çağrılır. Signal-slot mekanizması bu şekilde çalışır. Örneklerle birlikte bu kavramı daha iyi anlayacaksınız.

2. Öntanımlı (Default) İşaretler (Signals) Nedir? Öntanımlı İşaretler Nasıl Kullanılır ?

Öntanımlı (default) işaretler Qt tarafından önceden tanımlanmış parçacığa özgü işaretlerdir. Bu hazır işaretler çok rahatlıkla kullanılabilir. Yazının ilerleyen bölümlerinde öntanımlı işaretlerin kullanımını örneklerle daha iyi anlayacaksınız. Örneğin basılabilir tuşun (QPushButton) tıklandı (clicked), basıldı (pressed), bırakıldı (released) gibi öntanımlı işaretleri bulunmaktadır. Bu işaretleri fonksiyonlara bağladığınızda ve kullanıcı bu tuş üzerinde bir eylemde bulunduğunda ilgili fonksiyonlar çalıştırılır.


3. Qt Designer ile Signal - Slot Bağlantısı Nasıl Yapılır ?

Qt Designer ile signal-slot bağlantısı yapmak için öncelikle Qt Creator açılır ve yeni bir proje oluşturduktan sonra Qt Designer açılır. Qt Creator kullanımı, proje oluşturma, Qt Designer kullanımı hakkında bilgi edinmek için hazırlamış olduğum Qt Dersleri ücretsiz video serisini izleyebilirsiniz. Qt Creator'de Design Modunda yukarıda yer alan menüde bulunan Edit sekmesine tıklanır ve bu sekmede yer alan Edit Signals/Slots seçeneğine tıklanır.


Aynı işlemi F4 tuşuna basarak ya da aşağıdaki şekilde belirtilen tuşa basarak gerçekleştirebilirsiniz.


Signals-slots moduna geçmeden önce arayüz tasarımını tamamlamış olmalısınız ve arayüz üzerinde yer alan parçacıkların hangi işlevleri yapacağını belirlemiş olmanız gerekir. Signal-slot kavramını anlatabilmek için yatay kaydırma butonu (QHorizontalSlider) ve etiket (QLabel) parçacıklarından oluşan aşağıdaki tasarım yapıldı. Burada kaydırma butonunun konumu değiştirtirildiğinde o anki pozisyonunun değeri QLabel da gösterilecektir. Arayüz tasarımını tamamladık ve arayüzde yer alan parçacıkların ne iş yapacakları tanımlandıktan sonra yukarıda anlatıldığı gibi Signals/Slots moduna geçiş yapılır.


Signals-slots modunda iken Yatay Kaydırıcıya (HorizontalSlider) farenin sol tuşu ile tıklanır ve bu tuşa basılı tutularak etiketin (Label) üzerine getirilir ve burada tuş bırakılır. Tuşu bırakır bırakmaz Configure Connection adında yeni bir pencere açılacaktır. Bu pencerenin sol bölümünde yatay kaydırıcıya ait öntanımlı (default) işaretler bulunmaktadır. Biz burada değer değişti (valueChanged(int)) işaretini seçiyoruz. Bu işaret kaydırıcının değeri değiştiğinde işaret yayar. Biz bu işareti bir slot'a yani fonksiyona bağladığımızda kaydırıcının her değeri değiştiğinde bu fonksiyon çağrılacaktır.


İşaret seçimini yaptıktan sonra pencerenin sağ bölümü aktif hale gelir ve burada öntanımlı (default) slot'lar yani fonksiyonlar bulunmaktadır. Hem işaretler için hem de slot'lar için öntanımlı işaret ve slotları kullanabildiğimiz gibi kendi işaret ve fonksiyonlarımızı da Edit butonuna basarak tanımlayabiliriz. Biz burada etiket (Label) için setNum(int) fonksiyonunu seçiyoruz.





Yukarıda yer alan ekran görüntüsünde gördüğünüz gibi yatay kaydırıcının (HorizontalSlider) değeri değiştirildiğinde bu değer etikete (Label) yazdırılmaktadır. Burada basit bir şekilde herhangi bir kod yazmadan Qt Designer ile signal-slot bağlantısı gerçekleştirmiş olduk. Bu yöntem benim tercih ettiğim bir yöntem değil bu yüzden örnek sayısını arttırmadan ve daha fazla detaya girmeden konunun bu kadar yeterli olduğunu düşünüyorum. Kod yazarak signal-slot bağlantısının nasıl yapıldığını bir sonraki bölümde inceleyeceğiz.

4. Kod Yazarak Signal-Slot Bağlantısı Nasıl Yapılır ?

Bu bölümü Qt Designer'dan Go to slot özelliği ile kod yazarak signal-slot bağlantısı yapma ve connect() fonksiyonu ile signal-slot bağlantısı yapma olarak kendi içinde 2 alt başlık halinde inceleyeceğiz.

4.1. "Go to slot" ile Signal-Slot Bağlantısı

Qt Designer ile aşağıdaki ekran görüntüsünde yer alan bir buton (QPushButton) ve etiketten (QLabel) oluşan bir tasarım yapıyoruz. Bu tasarımda butona basınca etikette "butona basıldı" yazısı yazacak ve buton bırakıldığında "buton bırakıldı" yazacak.


Arayüz tasarımı ve arayüzde yer alan parçacıkların işlevleri tanımlandıktan sonra signal-slot bağlantısı için butonun üzerine farenin sağ tuşu ile tıklıyoruz ve açılan seçeneklerden Go to slot... seçeneğine tıklanır ve yeni bir pencere açılır.



Bu yeni pencerede QPushButton için öntanımlı (default) işaretler yer almaktadır. Burada "basıldı (pressed)" sinyalini seçip "OK" butonuna basıyoruz. Qt otomatik olarak bizim yerimize başlık dosyasında (mainwindow.h) ve kaynak dosyasında (mainwindow.cpp) slot yazmaktadır. Bizim tek yapmamız gereken kaynak dosyasında istediğimiz kodları yazmak.



Kaynak dosya içerisinde slot'un içerisinde etikete (QLabel) setText() fonksiyonu ile yazı yazdırıyoruz.


Aynı işlemleri "bırakıldı (released)" işareti için tekrar ediyoruz.





Qt Designer'da parçacığın üzerine farenin sağ tuşu ile tıklayarak "Go to slot" özelliğini kullandık ve signal-slot bağlantısının nasıl yapıldığını öğrendik. Bu yöntem öntanımlı (default) işaretler ile kullanılabilir ve benim arayüz geliştirirken sıklıkla kullandığım bir yöntem, sizin de kullanmanızı tavsiye ederim.

4.2. "connect()" fonksiyonu ile Signal-Slot Bağlantısı

Yazının başında kendimiz işaret (signal) tanımlayabilir miyiz diye sormuştuk, cevabımız evet. Qt'de öntanımlı (default) işaretler dışında istediğimiz işareti tanımlayabiliriz. Kendi tanımladığımız işareti slot'a bağlamak için connect() fonksiyonu kullanılır. Fonksiyonun kullanımı aşağıda belirtildiği gibidir.

connect( gönderen, SIGNAL(işaret_adı()), alıcı, SLOT(slot_adı()) )

  • Bir İşaret birden fazla Slot'a bağlanabilir


  • Birden fazla İşaret bir Slot'a bağlanabilir


  • Bir İşaret başka bir İşaret'e bağlanabilir


connect() fonksiyonunun kullanımını anlama ve yukarıda bahsedilen signal-slot özelliklerinin kullanımını öğrenebilmek için Qt Designer'da aşağıdaki ekran görüntüsünde yer alan tasarım yapılır.


mainwindow.h başlık dosyasında butona_basildi(), butona_basildi_2() ve butona_basildi_3() adında 3 tane işaret tanımlıyoruz. Bunlar Qt de varolan öntanımlı işaretler değil kendi tanımladığımız işaretler. Bir önceki bölümde Go to slot... özelliği ile tanımladığımız 2 tane slot'a ek olarak label_1_slot(), label_2_slot() ve label_3_slot() adında 3 tane slot tanımlıyoruz.


mainwindow.cpp kaynak dosyasında tanımladığımız işaretler ve slotları Yapıcı'da (constructor) connect() fonksiyonu ile birbirine bağlıyoruz. butona_basildi() işaretini label_1_slot(), label_2_slot() ve label_3_slot() adındaki slotlara bağlıyoruz ve bu bağlantı ile bir sinyalin birden fazla slot'a bağlanabildiğini görmüş olduk.


14 nolu satırda butona_basildi_2() işaretini label_1_slot() slotuna bağlıyoruz. Bu bağlantı ile birden fazla sinyalin aynı slot'a bağlanabildiğini görmüş olduk.

16 nolu satırda butona_basildi_3() işaretini butona_basildi() işaretine bağlıyoruz. Bu bağlantı ile bir sinyalin bir başka sinyale bağlanabildiğini görmüş olduk.

Kullanıcı arayüzde butona bastığında on_pushButton_pressed() slotu çalıştırılır. Bu slot içerisinde butona_basildi_3() işareti yayınlanır. İşaret yayınlamak için işaret adından önce emit ifadesi kullanılır. butona_basildi_3() işareti butona_basildi() işaretine bağlı olduğundan aynı zamanda butona_basildi() işareti de yayınlanmış olur. butona_basildi() işareti label_1_slot(), label_2_slot() ve label_3_slot() slotlarına bağlı olduğundan bu slotlar içerisinde yer alan kodlar çalıştırılır ve Etiketlere ilgili yazılar yazılır. Buton bırakıldığında on_pushButton_released() slotu içerisinde yer alan kodlar çalıştırılır ve etiketler üzerine hiçbir şey yazılmaz yani içerisinde önceden yazan yazılar silinir.

Son olarak belirtmem gereken konu işaretler ve slotlar parametre alabilir. Birbirlerine bağlanan işaret ve slotlar aynı sayıda ve tipte parametre alacak şekilde tanımlanmalıdır. Örneğin işarette 3 tane değişken tanımlanır ama slot'ta 2 tane değişken tanımlanırsa slot son parametreyi ihmal eder alamaz. Aynı türde olmayan değişkenler ise signal-slot arasındaki veri alışverişinde hataya sebep olacaktır.


5. Signal-slot bağlantısı nasıl kaldırılır (iptal edilir)?

Signal-slot bağlantısı yaparken connect() fonksiyonunu kullanarak yazmış olduğumuz ifadenin aynısını disconnect() ifadesiyle yazıyoruz.

disconnect( gönderen, SIGNAL(işaret_adı()), alıcı, SLOT(slot_adı()) )

Signal-slot bağlantısının iptal edilmesi çok sık kullanılan bir yöntem değildir ama arayüz geliştirirken ihtiyaç duyacağınız durumlar olabilir.


Signal-slot mekanizması kolay ve esnek kod yazmamızı sağlayan Qt nin sağlamış olduğu en önemli özelliklerden biridir. Bu yazıda signal-slot kavramını, signal-slot mekanizmasının nasıl çalıştığını, nasıl signal-slot bağlantısının yapıldığını elimden geldiğince anlatmaya çalıştım.

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.