Dlib (C++) Kütüphanesinin Windows'a Kurulumu ve Qt ile Kullanılması
Dlib, yapay öğrenme - makine öğrenmesi (machine learning) algoritmalarını içeren C++ kütüphanesidir ve günlük hayatımızda karşılaştığımız problemleri çözmek için kullanabileceğimiz kompleks yazılımlar geliştirebileceğimiz bir araçtır. Yüz tanıma (face recognition), yüz tespiti (face detection), yüz modelleme (facial landmarks) gibi uygulamaları Dlib kütüphanesi ile kolayca geliştirebilirsiniz. Dlib, C++ programlama dili ile kullanılan bir araç olmasının yanında Python programlama dili ile de kullanılabilmektedir. Python ile kullanmak için kurulumunuzu ona göre yapmanız gerekmektedir. Bu yazımda C++ dili için kurulum yapılacaktır ilerleyen günlerde Python dili için kurulumun nasıl yapıldığını anlatmayı planlıyorum. Aşağıdaki adımları takip ederek Windows işletim sisteminize Dlib kütüphanesinin kurulumunu yapabilir ve Qt ile uygulama geliştirebilirsiniz.
Adım 1.
Dlib kütüphanesinin en son yayınlanan versiyonu sitesinden indirilir (Bu yazıda 19.16 versiyonu indirildi). Dlib, hızlı gelişim gösteren bir kütüphane olduğunda sürekli yeni versiyonları çıkmaktadır.
Adım 2.
İndirilen sıkıştırılmış dosya (dlib-19.16.zip) çıkarılır.
Adım 3.
dlib-19.16 klasörü içerisine "build" adında boş bir klasör oluşturulur.
Adım 4.1.
Kurulum için cmake-gui'den faydalanacağız. Öncelikle sitesinden işletim sisteminizin 32 bit ya da 64 bit olmasına göre .zip uzantılı cmake dosyası indirilir.
Adım 4.2.
İndirilen sıkıştırılmış dosya çıkarılır.
Adım 4.3.
Çıkartılan klasör içerisinde bulunan "bin" klasörünün içerisinde yer alan "cmake-gui.exe" çift tıklanarak açılır.
Adım 5.
"Where is the source code:" yazan bölümde indirmiş olduğumuz dlib-19.16 klasöründe bulunan "dlib" klasörü "Browse Source ..." butonuna basılarak seçilir.
"Where to build the binaries:" yazan bölümde indirmiş olduğumuz dlib-19.16 klasöründe sonradan oluşturduğumuz "build" klasörü "Browse Build ..." butonuna basılarak seçilir.
ve aşağıda yer alan "Configure" butonuna basılır.
Adım 6.
(1. yol)
"Configure" butonuna bastıktan sonra yeni bir pencere açılacaktır. Bu pencerede derleme işlemi için kullanılacak derleyicinin seçilmesi istenmektedir. Ben daha önce bilgisayarıma Qt'nin MinGW derleyicisi ile kurulumunu yaptığım için burada yine tanımlı yerel (default native compiler) MinGW derleyicisini seçiyorum. Windows'a Qt Kurulumu için yazımı buradan inceleyebilirsiniz.
(2.yol)
"Specify native compilers" seçeneği ile yerel derleyicilerinizi kendiniz belirleyebilirsiniz. Burada eğer Qt kurulumu yaptıysanız " Qt > Qt5.11.1 > Tools > mingw530_32 > bin " klasöründe yer alan gcc.exe C derleyicisi olarak g++.exe C++ derleyicisi olarak seçilebilir.
Adım 7.
Derleyiciyi seçtikten sonra konfigürasyon işlemi başlayacaktır. "Configuration done" mesajını görene kadar bekleyiniz. Konfigurasyon işlemi sırasında Dlib kütüphanesi ile kullanılabilecek diğer araçların bilgisayarınızda kurulu olup olmadığına bakılır ve sonunda size bunlar hakkında bilgiler verir. Aşağıdaki ekran görüntüsünü inceleyecek olursak bilgisayarımda CUDA ve BLAS araçlarının kurulu olmadığını ve Dlib kütüphanesinin bu araçları kullanamayacağı belirtilmiş. Eğer CUDA kurulumunu önceden yapmış olsaydım Dlib kütüphanesini kullanarak geliştirdiğim algoritmayı GPU üzerinde çalıştırabilecektim. Buradan JPEG ve PNG formatlarındaki resimlerin Dlib ile kullanılabileceği gibi detaylı bilgilere ulaşmak mümkün. Ben sadece bir kaçından bahsettim siz detaylı inceleyebilirsiniz. Burada şimdilik bu konfigurasyonun yeterli olduğunu düşünerek "Generate" butonuna basıyoruz. "Generating done" mesajını gördüysek kuruluma başarılı bir şekilde devam ediyoruz demektir.
Adım 8.
Komut satır programı (cmd, terminal) açılır ve derleme işleminin gerçekleştirildiği "build" klasörüne geçilir.
mingw32-make
komutu çalıştırılır. Bu komutu hızlı derleme için mingw32-make -j4
formatında da yazabilirsiniz. Burada "-j4" ifadesiyle derleme esnasında bilgisayarın 4 çekirdeğininde kullanılması gerektiği belirtilir. Kullanılacak çekirdek sayısını arttırıp azaltabilirsiniz. Ancak bu şekilde birden fazla çekirdek kullanılarak derleme yapıldığında hata alınabilmektedir. Benim tavsiyem tek çekirdek ile derleme işlemini yapmanız.
Adım 9.
dlib-19.16 klasörü içerisinde "include" adında boş bir klasör oluşturuyoruz ve "dlib" klasörünü bu boş klasör içerisine taşıyoruz.
Adım 10.
Sisteminize Qt kurulumu yaptıktan sonra Qt Creator açılır ve yeni proje oluşturulduktan sonra proje dosyasına (.pro uzantılı dosya) dlib kütüphanesinin derlendiği klasörün yolu aşağıdaki gibi tanımlanır.
Kurulum esnasında CUDA ve BLAS ile derleme yapılmadıysa sadece Dlib kütüphanesinin derlendiği klasörün yolunu tanımlamamız yeterlidir. CUDA ve BLAS ile derleme yapıldıysa Dlib kütüphanesinin derlendiği klasörün yolu ile CUDA ve BLAS kütüphanelerinin yolunu da tanımlamamız gerekmektedir.
Qt proje dosyasında (.pro) kütüphane tanımlanırken -L(kütüphane yolu), -l(kütüphane) şeklinde önekleri kullanılmaktadır.
(Kısa yol)
Yukarıda anlatılan yöntemle proje dosyasına dlib kütüphanesinin derlendiği klasör yolunu tanımladığınızı ve bu şekilde onlarca proje oluşturduğunuzu düşünün. Yeni bir dlib versiyonu çıktığında ya da klasörü farklı bir yere taşıdığınızda oluşturduğunuz onlarca projeyi tek tek açarak bu tanımlamaları düzeltmeniz gerekecektir. Bu sıkıntılı durumu yaşamamak için yukarıda yapılan tanımlar bir text dosyası açılarak buraya yazılır. Daha sonra ".txt" olan dosya uzantısı ".pri" olarak değiştirilir ve bu dosya aşağıda tanımlandığı gibi Qt proje dosyasına (.pro) eklenir.
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 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 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 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 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 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
defclear_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
defshow_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.
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.
importsysfromPySide2.QtWidgetsimportQApplication,QWidgetfromPySide2.QtUiToolsimportQUiLoaderfromPySide2.QtCoreimportQFileclassMyWidget(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")defclear_text(self):self.ui.label_text.clear()defshow_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.
Qt bir Grafiksel Kullanıcı Arayüzü (GKA, Graphical User Interface, GUI) geliştirme aracıdır. Qt'yi tercih etmemin sebebi hem kolay bir şekilde arayüz geliştirme imkanı sunması hem de birçok platformda (işletim sisteminde, Windows, Linux, Mac) kullanılabiliyor olması. Qt ile arayüz geliştirirken C++ Programlama dili kullanılmaktadır. Python programlama dilinin son yıllarda popülerliği giderek artmaktadır ve yapay zeka, veri bilimi gibi alanlarda en çok tercih edilen programlama dilidir. C++ programlama dili ile veri işlemek Python programlama diline göre biraz daha zordur. Bu sebeple arayüz geliştirme için mükemmel bir araç olan Qt'nin Python ile kullanılabiliyor olması benim açımdan çok önemli. Tkinter, Python için GUI tasarımında kullanılan bir araçtır ama genel olarak Tkinker hakkında olumsuz yorumlarla karşılaştım. Qt'nin Python ile kullanılması için Riverbank'ın geliştirdiği PyQt programı mevcuttur ama bu Qt'nin Resmi olarak desteklediği bir araç değildir. PyQt'nin kurulumu ve Uygulama geliştirmek için aşağıdaki bağlantıları kullanabilirsiniz.
Yakın zamanda Qt'nin resmi olarak desteklediği
(Python için Qt) Qt for Python PySide2
kullanıcılara sunuldu. Bu yazımızda PySide2'nin hem Windows hem de Ubuntu 16.04 için kurulumunu gerçekleştireceğiz. Kurulum için 3 farklı yöntem mevcuttur:
3 numaralı yöntem ile kurulum çok kolay değil bu sebeple tavsiye etmiyorum. Eğer kaynak kodlarından derleme yapacaksanız ilgili kaynak kodlarını 2 nolu yöntem için verilen linkte bulabilirsiniz. 2 numaralı yöntem için Qt sitesinde bulunan .whl uzantılı wheel kurulum dosyalarından işletim sisteminiz ve kullanacağınız Python versiyonuna göre bir seçim yapmanız gerekiyor. Linux için hem Python2 hem de Python3 için kurulum dosyası mevcuttur ancak Windows için sadece Python 3 için kurulum dosyası mevcuttur. Python wheel nedir ? Nasıl Kurulum Yapılır ? sorularının cevaplarını önceki yazımda bulabilirsiniz.
Biz burada 1 nolu yöntem ile yani pip komutu kullanarak kurulum yapacağız. PySide2 kurulumu yapabilmek için işletim sisteminizde Python daha önceden kurulmuş olmalıdır. Eğer işletim sisteminizde kurulu Python versiyonu yoksa Python Kurulumu için önceki yazımı takip edebilirsiniz. Dikkat etmeniz gereken bir diğer konuda PySide2 ile uyumlu bir Python versiyonuna sahip olmanızdır. Bu yazının yazıldığı tarih itibariyle geçerli PySide2 ile uyumlu Python versiyonlarını aşağıdaki ekran görüntüsünde ya da PyPI'dan kontrol edebilirsiniz.
Pip ile kurulum yapmak için aşağıdaki komut çalıştırılır.
pipinstallPySide2
1. Windows için PySide2 Kurulumu
Aşağıdaki video'yu izleyerek Windows için PySide2 kurulumunu gerçekleştirebilirsiniz. Hem de kurulumun başarılı olup olmadığını nasıl test edeceğinizi öğrenebilirsiniz.
2. Ubuntu için PySide2 Kurulumu
Aşağıdaki video'yu izleyerek Ubuntu için PySide2 kurulumunu gerçekleştirebilirsiniz. Hem de kurulumun başarılı olup olmadığını nasıl test edeceğinizi öğrenebilirsiniz. Sisteminizde birden fazla Python versiyonu kurulu ise kurulumun başarılı bir şekilde yapılabilmesi için pip ve pip3 komutlarının hangi Python versiyonu için kurulumu gerçekleştireceğini kontrol etmelisiniz. pip ve pip3 komutlarının kullanımı için önceki yazımı inceleyebilirsiniz. Ya da bu tür sıkıntılarla uğraşmamak için python'un farklı versiyonları için farklı sanal ortamlar kurabilirsiniz. Sanal ortam kurulumu ve kullanımı hakkında ilgi almak için aşağıda linkte verilen yazımı takip edebilirsiniz.
Python Sanal Ortam (virtualenv, virtualenvwrapper) Kurulumu/ Kullanımı
PyQt5 ile Grafiksel Kullanıcı Arayüzü (GUI) Geliştirme
PyQt5 ile Grafiksel Kullanıcı Arayüzü (GKA; Graphical User Interface, GUI) tasarımı yapmak için birçok seçeneğimiz var. Bunları 3 başlık altında toplamak mümkün. GUI tasarımını aşağıdaki yöntemlerle gerçekleştirebiliriz.
GUI tasarımını Kod yazarak gerçekleştirme
Qt Designer ile tasarım yapıp tasarımı Python kodlarına çevirme
Qt Designer ile tasarım yapıp bu tasarımı loadUi modülü yardımıyla Python kodlarında kullanmak
Burada PyQt5 kurulumu yaptığınızı varsayıyorum eğer yapmadıysanız PyQt5 kurulumu için önceki yazımı takip edebilirsiniz.
Windows'a PyQt5 Kurulumu
Tasarıma geçmeden önce belirtmem gereken diğer bir husus da PyQt5 ile GUI tasarımı yaparken kullanacağımız GUI araçları hakkında ilgili dökümanlara nasıl ulaşacağımızı bilmemiz konusudur.
PyQt5 sınıf, metod ve fonksiyonlarına aşağıdaki yolu izleyerek ulaşabiliriz:
Başlat > Tüm Programlar > PyQt GPL v5.6 for Python v3.5 (x64) > Documentation > PyQt Reference Guide
bu yolda belirtilen klasör ismi sizin kurmuş olduğunuz PyQt5 versiyonuna göre farklı olabilir.
Kurulum ve PyQt5 dökmümanlarına ulaşma konusundan bahsettikten sonra arayüz geliştirme yöntemlerine geçebiliriz.
1. Kod Yazarak Arayüz Geliştirme
Tüm 3 yöntem için de aynı arayüzü tasarlayacağız. Bunun için hem basit hem de sinyal-slot yapısını kullanacağımız bir tasarıma karar verdim. Qt'nin en önemli özelliklerinden biri de sinyal-slot(yuva) yapısıdır. Bu yapıyı bir örnekle açıklamaya çalışalım. Arayüzde bir tuşa bastığımızda tıklandı (clicked) sinyali yayınlanır ve bu tuşa basıldığında yapılacak işleri (dosya seçme, kamera açma, yazıyı silme, aklınıza gelebilecek herşey) yazdığımız slot'da belirtmemiz gerekir. Slot burada bir fonksiyondur. Bizim tek yapmamız gereken sinyal ile slot bağlantısını "connect" işlevi ile tanımlamak. 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 "Merhaba PyQt5" yazmaktadır. Temizle düğmesi ile etikette yazan yazı silinmektedir. Göster düğmesi ile etikete yeniden "Merhaba PyQt5" yazılmaktadır.
Bu arayüzü elde etmek için yazacağımız kod aşağıda belirtilmiştir.
1 nolu satır yorum satırıdır. Burada isterseniz yorum satırında belirtildiği gibi kullanacağınız arayüz bileşenlerini tek tek ekleyebilirsiniz ya da 2 nolu satırda belirtildiği gibi
QtWidgets
sınıfına ait tüm bileşenler eklenir. 3 nolu satırda
QtCore
sınıfına ait metodlar eklenir.
6
7
classfirst_GUI(QWidget):def__init__(self):
6 nolu satırda
QWidget
sınıfından ürettiğimiz "first_GUI" 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.
8 ve 9 nolu satırlar yorum satırıdır. Bu satırları yazmamın sebebi 10 nolu satıra alternatif olarak kullanılabiliyor olmalarıdır.
super()
fonksiyonu miras alma (inheritance) durumunda kullanılan miras aldığımız bir üst (parent, base) sınıfın nitelik ve metodlarını kullanmamızı sağlar. 8 nolu satır eski tip super() fonksiyonudur. 9 nolu satır ise Python 3 ile yeni kullanılmaya başlayan super() fonksiyonudur. 10 nolu satır ile üst sınıfın __init__() fonksiyonu çağrılır. 10 nolu satırı ya da yerine 9 nolu satırı yazmaksak programımızı çalıştırdığımızda hata alırız.
12 nolu satırda
QLabel
etiket parçacığı (widget) "Merhaba PyQt5" 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.
13 nolu satırda etiket içerisinde yazan yazının hizalaması ortalanmıştır. Bu hizalamayı
setAlignment
fonksiyonu sağlamaktadır.
14 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.
16 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 17 nolu satırda
setMinimumHeight
fonksiyonunu kullanarak tanımlıyoruz. 18 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 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. 19, 20 ve 21 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.
23 ve 24 nolu satırlar sinyaller ile fonksiyonları (slotları) birbirine
connect
metodunu kullanarak bağladığımız satırlar. "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.
26 nolu satırda dikey yerleşim düzeni (
QVBoxLayout
) tanımlıyoruz ve 27, 28, 29 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.
31
32
33
self.setLayout(vertical_layout)self.setWindowTitle("PyQt5 first GUI")self.resize(400,300)
31 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. 32 nolu satırda arayüzün gösterileceği pencerenin adının "PyQt5 first GUI" olmasını
setWindowTitle
fonksiyonunu kullanarak sağlıyoruz. 33 nolu satırda açılacak pencerenin boyutlarını yüksekliği 300 piksel, genişliği 400 piksel olacak şekilde
resize
fonksiyonunu kullanarak ayarlıyoruz. Bu satır ile "first_GUI" sınıf tanımlaması bitmiştir.
36
37
defclear_text(self):self.label_text.clear()
36 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.
39 ve 40 nolu satırlarda "Göster" düğmesinin "show_text()" slotu tanımlanmaktadır. Bir etikete yazı yazmak için kullanılan
setText()
fonksiyonu ile bu düğmeye tıklandığında "Merhaba PyQt5" yazısı yazacaktır. Bu düğmenin yaptığı işi gözlemlemek için öncelikle etikette yazan yazı silinmelidir.
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. 43 nolu satırda "first_GUI" adında tanımladığımız sınıftan "widget" adında bir nesne tanımlıyoruz. Bu nesnenin
show()
fonksiyonunu kullanarak arayüz için oluşturduğumuz pencereyi gösteriyoruz (44 nolu satır). 45 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 kullanıcı arayüzü geliştirmiş olduk. Python kodlarından farklı olarak yazdığımız kodu (Windows için)
.pyw
uzantılı olarak kaydediyoruz.
İlk yöntemde her şeyi kod yazarak tanımladık. Bu çok uzun bir işlem olmasa da Qt Designer ile tasarım yapmak sizin için uygun olabilir. Bunun için PyQt5 kurulumu ile birlikte gelen Qt Designer açılır.
Kod yazarak yaptığımız tasarımın aynısını Qt Designer ile yaptık. Aşağıdaki videoyu izleyerek tasarımın nasıl yapıldığını izleyebilirsiniz.
Qt Designer ile yapılan tasarımı
.ui
uzantılı olarak kaydediyoruz. Daha sonra komut satır (cmd) programı açılır. Tasarımı kaydettiğimiz klasöre geçiyoruz ve Python kurulumunun gerçekleştiği klasörde yer alan (“C:\Program Files\Python35\Lib\site-packages\PyQt5\")
pyuic5.bat
designer ile (.ui uzantılı) yaptığımız tasarım ve bunun Python kodlarına çevrileceğinde hangi isimle kaydedileceğini tanımlayarak çalıştırılır. Örnek kodu aşağıda bulabilirsiniz.
Bu kodu çalıştırarak tasarımı Python kodlarına çevirdik. Tasarımda yapacağımız her işlemden sonra kodu çalıştırarak bu dönüşümü gerçekleştirmemiz gerektiğinden yazacağımız kodları otomatik oluşturulan bu Python koduna yazmıyoruz bunun yerine bu kodu kullanacak başka Python kodu (wrapper) yazacağız. Qt Designer ile tasarım yaptığımızda sinyal-slot bağlantısı için 3 farklı yöntem mevcuttur.
Kod yazarak sinyal-slot bağlantısı yapma
Qt Designer ile sinyal-slot bağlantısı yapma
@pyqtSlot() ile sinyal-slot bağlantısı yapma
2.1. Kod Yazarak Sinyal-Slot Bağlantısı Yapma
Python koduna dönüştürülen tasarımı kullanmamızı sağlayan ve sinyal-slot bağlantısının kod yazılarak yapıldığı Python kodunu (wrapper) aşağıda bulabilirsiniz.
Burada satır satır açıkladığımız ilk yöntemden farklı olarak 2 nolu satırda .py uzantılı tasarımın Python kodlarına dönüştürüldüğü dosya adını kullanarak (designer_example)
Ui_MainWindow()
modülü eklenmiştir.
8 ve 9 nolu satırlarda tasarım kodumuz mevcut Python koduna eklenmiştir. Bu işlem için
setupUi()
fonksiyonu kullanılmıştır ve ilk yöntemden farklı olarak atama self değişkenine değil de
self.ui
değişkenine yapılmıştır.
11 ve 12 nolu satırlarda kod yazarak sinyal-slot bağlantıları yapılmıştır. Diğer satırlarda yer alan kodlar ilk yöntemde açıklandığından burada tekrar açıklanmayacaktır.
2.2. Qt Designer ile Sinyal-Slot Bağlantısı Yapma
Sinyal-Slot bağlantısını kod yazarak değil de Qt Designer ile de yapabilirsiniz. Yazı ile bu işlemi anlatmak zor olduğundan dolayı aşağıdaki videoyu izleyerek bağlantının nasıl yapıldığını öğrenebilirsiniz.
Burada
2.1
yönteminde yazmış olduğumuz Python kodlarında yer alan sinyal-slot bağlantılarının yapıldığı 11 ve 12 nolu satırları siliyoruz çünkü bu satırlara ihtiyacımız yok. Bu satırları sildikten sonra kalan kısımları tasarımı yükleme ve tasarlanan arayüzü çalıştırmak için kullanabilirsiniz.
2.3. @pyqtSlot() ile Sinyal-Slot Bağlantısı Yapma
pyqtSlot dekoratörü ile sinyal-slot bağlantısının nasıl yapıldığını aşağıdaki video'yu izleyerek öğrenebilirsiniz.
Qt Designer ile yapmış olduğumuz tasarımı kullanabilmek için yazmış olduğumuz Python kodlarında sinyal-slot bağlantısı için pyqtSlot dekoratörü kullandığımızda slot tanımlamalarından bir satır önce
@pyqtSlot()
ifadesi eklenir. Burada Slot ismini belirlerken istediğimiz ismi yazamıyoruz belirli bir kurala göre isimlendirme yapmamız gerekiyor. İsimlendirmede kullanacağımız parçacığın nesne adı (object name, bunu designer'dan parçacığa tıkladığımızda sağ tarafta görebilirsiniz) ve kullanılacak sinyal aşağıdaki formatta yazılır:
on_
nesne_adi_
sinyal_adi()
Örnek slot tanımlamalarını aşağıdaki Python kodunun 14 ve 18. satırlarında görebilirsiniz.
Burada önceki kodlardan farklı olarak
QtCore
sınıfından
pyqtSlot
2 nolu satırda gösterildiği gibi eklenir.
3. Qt Designer ile Tasarım + loadUi modülü ile bu Tasarımı Kullanma
İkinci yöntemde tasarımda yaptığınız her değişiklik sonrasında tasarımı Python kodlarına çevirmek için pyuic.bat çalıştırılır. Bu kod çalıştırma işlemi size zahmetli bir iş olarak gelebilir. Tüm bunlarla uğraşmadan Qt Designer ile yapmış olduğunuz tasarımı kolay bir şekilde dönüşüm yapmadan kullanabileceğiniz bir yöntem mevcut. Qt Designer ile yapmış olduğumuz tasarımı kullandığımız Python kodu aşağıda verilmiştir.
Burada diğer yazdığımız kodlardan farklı olarak 4 nolu satırda
uic
modülünde yer alan
loadUi
fonksiyonu eklenmiştir ve bu fonksiyon 10 nolu satırda .ui uzantılı tasarımı yüklemek için kullanılmıştır. Burada sinyal-slot bağlantısı
2.3
bölümünde anlatıldığı gibi pyqtSlot() dekorlayıcısı kullanılarak yapılmıştır. Diğer kodlar daha önce açıklandığından tekrar açıklanmayacaktır. Sanırım PyQt5 ile GUI geliştirmek için en ideal yöntem son olarak bahsettiğimiz üçüncü yöntem gibi gözüküyor.