PyQt nedir ve neden PyQt
Qt arayüz kitaplığını python ile kullanabilmenizi sağlayan şeydir. Benim için “neden qt” sorusunun cevabı kolay kodlama ve sistem uyumudur. Buna ek olarak içinde birçok modül barındırmasını da diyebiliriz fakat pythonun zengin kütüphaneleri sayesinde bunlara pek fazla ihtiyaç duymayacağız.
PyQt’yi buradan indirip kurabilirsiniz. Eğer linux kullanıyorsanız dağıtımınızın paket yöneticisinden kolayca kurabilirsiniz. PyQt ile beraber bazı programlar geliyor bunlar:
- Designer: Görsel olarak formlar hazırlamamızı sağlayacak uygulama.
- Linguist: PyQt’nin büyük nimetlerinden biri olan çeviri sisteminin bir aracı.
- Assistant: Qt belgelerine buradan erişebilirsiniz. İlerleyen zamanlarda işinize çok yarayacak.
Bilmeniz gereken birkaç şey:
Qt’deki her parçacık QObject’lerden türemiştir. Görsel şeyler ise(label, buton, textbox vs) QObjectten türemiş QWidgetlerdir. Yani bir QLabel hem QObjectin hemde QWidget’in özelliklerini hemde kendi özelliklerini içerir. Bu gereksiz bilgiden sonra devam ediyoruz:
Efsane Merhaba Dünya Uygulaması
Bomboş bir pencere gösteren bir uygulama yapacağız şimdi. Hemen favori metin editörünüzü açın ve içine şunları yazın:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # -*- coding: utf-8 -*-
import sys # sys modülünü yükledik
from PyQt4 import QtGui # PyQt4'ün gui modülünü yükledik
def main(): # main adında bir fonksiyon oluşturduk.
app = QtGui.QApplication(sys.argv) # her pyqt uygulaması bir qapplication içermek zorundadır.
# dolayısıyla bizde bir tane tanımladık.
mw = QtGui.QMainWindow() # mw adında bir mainwindow tanımladık
mw.setWindowTitle(u"Merhaba Dünya") # mw'nin başlığnı Merhaba Dünya olarak değiştirdik.
# u koymamızın sebebi Türkçe karakterleri doğru gösterebilmek.
mw.resize(100, 100) # penceremizin boyutunu değiştirdik.
mw.show() # ve pencereyi gösterdik.
return app.exec_() # böylece uygulamamızı başlatık.
if __name__ == "__main__": # python dosyamız çalıştırıldığında:
main() # main adlı fonksiyonumuz çalışsın dedik. |
Bu kod ile böyle bir şey elde ettik:
Şimdi işleri biraz daha karıştıralım mesela penceremizin içine bir label birde button koyalım ve bunların yazılarını değiştirelim. Kodlarımızı şu şekilde düzenliyoruz:
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
| # -*- coding: utf-8 -*-
import sys
from PyQt4 import QtGui
def main():
app = QtGui.QApplication(sys.argv)
# Penceremiz ile ilgili işlemler:
mw = QtGui.QMainWindow()
mw.setWindowTitle(u"Merhaba Dünya")
mw.resize(300, 100)
# Penceremizin içerikleri:
layout = QtGui.QVBoxLayout()
# Bir düzen kutusu oluşturduk.
#Bunlar form tasarımında bize kolaylık sağlar.
# Buradaki bir VerticalBoxLayout.
#Yani öğeleri dikey olarak sıralıyor.
#QMainWindow birçok özelliğe sahiptir. Üzerine toolBar'lar dockWindowlar
#statusBarlar ekleyebilirsiniz. Bunların hepsinin ayrı bir alanı vardır.
#Diğer ekleyeceğiniz öğeler başka bir widget üzerinde olmalıdır.
#o yüzden bir widget oluşturuyoruz.
w = QtGui.QWidget() # Widgetimizi oluşturduk.
mw.setCentralWidget(w) #ve widget'imizi formun ana widgeti olarak belirledik.
label = QtGui.QLabel() # Bir label yani yazı alanı oluşturduk.
label.setText(u"Ben bir labelim ve buda benim yazım!")
button = QtGui.QPushButton() # Bir pushbutton oluşturduk.
button.setText(u"Ben bir QPushButtonum!") #buttonun üzerindeki yazıyı değiştirdik.
layout.addWidget(label)
layout.addWidget(button)
# Yukarıda oluştuduğumuz öğeleri layoutun içine yerleştirdik.
mw.centralWidget().setLayout(layout) #yukarıda setCentralWidget() ile eklediğimiz widget'e
#bu şekilde ulaşabilirsiniz.
#isterseniz bu kodu w.setLayout(layout) olarak da kullanabilirsiniz.
#Bu kod ile layout öğesini w'nin içine yerleştirdik.
mw.show() # Penceremizi gösterdik.
return app.exec_()
if __name__ == "__main__":
main() |
Şöyle bir görüntü elde ettik:
Bu örnekte bir QMainWindow kullanmıştık. QMainWindow kullanmadan istediğimiz her widget’i bir pencere gibi gösterebilirz bu işimizi biraz basitleştirebilir ama QMainWindow’un nimetlerinden yararlanmamızı engelleyebilir. Böylede bir örnek yapalım:
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
| import sys
from PyQt4 import QtGui
def main():
app = QtGui.QApplication(sys.argv)
w = QtGui.QWidget() # Widgetimizi oluşturduk.
w.setWindowTitle(u"Merhaba Dünya")
w.resize(300, 100)
# Penceremizin içerikleri:
layout = QtGui.QVBoxLayout()
label = QtGui.QLabel()
label.setText(u"Ben bir labelim ve buda benim yazım!")
button = QtGui.QPushButton()
button.setText(u"Ben bir QPushButtonum!")
layout.addWidget(label)
layout.addWidget(button)
w.setLayout(layout)
w.show() #widget gösterdik.
return app.exec_()
if __name__ == "__main__":
main() |
Bu kodlar ile yine aynı görüntüyü elde edeceğiz. Bu şekilde kodları elimizle yazıp penceremizi oluşturabiliyoruz. Bu sefer Qt Designer kullanalım ve işe yarar bir uygulama yapalım ama uygulama geçmeden önce:
Sinya/Slot Kavramı
Örneğimize devam etmeden önce sinyal slot kavramı üzerinde duralım. Nedir bu? Örneğin formunuzda bir button var. Buna tıkladığınızda bir şeyler yapmasını istiyorsunuz. Yani buttona tıklandığında bir sinyal çıkıyor ve o sinyali bir slot’a bağlayarak işlemlerimizi yapıyoruz. Örnek içinde kullanımını göreceksiniz:
Qt Designer Kullanarak Yapılan Bir Uygulama
Öncelikle Qt Designeri açıyoruz karşımıza bir diyalog geliyor, oradaki listeden “Main Window”a çift tıklıyoruz. Aşağıdaki gibi bir form tasarımı yapıyoruz.
Ve formun boş bir yerine tıklayıp resimde belirttiğim düğmeye basıyoruz. Böylece parçacıkların yerini otomatik düzenledi. Sonrasında bunu “form.ui” adında kaydediyoruz. Gördüğünüz gibi bir python dosyası değil ui dosyası oluştu.
Bu dosyayı kullanmanın 2 yolu var. Birincisi dosyayı python koduna çevireceğiz ve öyle kullanacağız. ikincisi bir modül yardımıyla bu dosyayı direk kullanacağız. Şimdi her ikisinide görelim.
Birinci yöntemi kullanmak için önce dosyayı python koduna çevirmeliyiz. dosyayı kaydettiğiniz yere gelin ve konsolu açın. Sonra şu komutu verin: “pyuic4 form.ui -o ui_form.py”. Böylece ui_form.py adında bir python dosyası elde ettik. Şimdi bu dosyayı kullanarak uygulamamızı yapalım. Aynı dizin içine form.py adında bir dosya oluşturun ve içeriğini şu şekilde değiştirin:
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
| # -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui #PyQt4'den QtCore ve QtGui'yi dahil ettik
from ui_form import Ui_MainWindow #ui_form.py dosyasının içindeki
#Ui_MainWindow adlı sınıfı dahil ettik
class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
#MainWindow adında bir sınıf oluşturduk.
#QtGui.QMainWindow diyerek mainwindow yaptık kendisini.
#Ui_MainWindow kullanabilmek için oraya ekledik.
def __init__(self): #ana işlemlerin olduğu sınıf
QtGui.QMainWindow.__init__(self)
self.setupUi(self) #Ui_MainWindow'ın içindeki setupUi fonksiyonuyla
#formumuzu yükledik.
self.pushButton.clicked.connect(self.dosyaAc)
#Bu şekilde pushButtonun clicked olayını(yani tıklama olayını)
#dosyaAc adındaki fonksiyonumuza bağladık.
#Özetlersek pushButtona tıklandığında dosyaAc fonksiyonu çalışacak.
self.pushButton_2.clicked.connect(self.kaydet)
#aynı şekilde bunu da kaydet fonksiyonuna bağladık.
"""
Yukarıdaki gibi sinyalleri bağlayabileceğiniz gibi
self.connect(self.pushButton, QtCore.SIGNAL("clicked()"), self.dosyaAc)
şeklinde de bağlayabilirsiniz. Ama diğer yöntem daha basit.
"""
self.dosya = ""
def dosyaAc(self):
self.dosya = unicode(QtGui.QFileDialog.getOpenFileName(self, u"Düzenlenecek dosyayı seçin", ".", u"Bütün Dosyalar (*.*)"))
#Bir diyalog göstererek dosya seçilmesini istedik.
#Gelen dosya yolunu self.dosya'ya eşitledik.
f = open(self.dosya, 'r')#dosyamızı okuma modunda açtık
self.plainTextEdit.setPlainText(unicode(f.read()))
#dosyanın içeriğini okuyup plainTextEdite koyduk.
f.close()
def kaydet(self):
file = open(self.dosya, 'w') #yazma modunda dosyayı açtık
file.write(self.plainTextEdit.toPlainText()) #dosyanın içine yazdık
file.close()
def main():
app = QtGui.QApplication(sys.argv)
mw = MainWindow()
mw.show()
return app.exec_()
if __name__ == "__main__":
main() |
Bu performanslı ama biraz uzun yoldu. Şimdi ui dosyasını nasıl direkt olarak kullanacağımızı görelim. Bu sefer sadece farklılıkları yazıyorum:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui, uic #ek olarak uic modülünü dahil ettik
#gördüğünüz gini ui_form.py'yi import etmedik çünkü onunla işimiz yok
#bu sefer direk ui dosyasını kullanacağız.
class MainWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
uic.loadUi("form.ui", self)
#Bu sefer bu komutu kullanarak formumuzu yükledik.
#Birinci paranametre olarak ui dosyasnının yolunu girdik.
#Diğer kodlarda değişen bir şey yok. |
Bu yöntemin yararı her seferinde ui dosyasını py dosyasına dönüştürme zorunluluğunuzun olmaması. Biraz daha performanssız ama çok çok fazla form vs kullanmadıkça bir sorun olacağını sanmam.
Evet ilk dersin sonuna geldik
. Şuan çok yoruldum, zaten yorgundum. Pek düzgün anlatamamış olabilirim, anlamadığınız yerler olabilir sorunlarınızı/sorularınızı buraya yazarsanız cevaplamaya çalışırım
Diğer derste daha gelişmiş bir uygulama yapıp resource ve yerelleştirme sistemini anlatmaya çalışacağım