PyQT Dersleri - 3

Önceki yazımızın sonlarına doğru belirttiğimiz gibi, bu yazıda çok basit işlevleri olan bir metin düzenleyicisi yapacak ve Python’un setuptools kitaplığını kullanarak uygulamamızı nasıl dağıtıma hazır hale getireceğimizi göreceğiz. Burada anlatılanları anlamak için önceki yazıları (1. ve 2. ders) mutlaka okumanız gereklidir.

Bu ayki yazımızda yapacağımız uygulama, şimdiye kadar anlatılan bütün konuları kapsamakta. PyQt ile birkaç tane uygulama yazdıktan sonra, programın dağıtıma hazır hale getirilmesi gibi bazı işleri sürekli tekrar etmektense, ilerleyen PyQt uygulamalarında kullanabileceğim çok basit bir iskelet yapısı oluşturdum. Artık bir uygulamaya başlarken bu iskelet yapı üzerinden ilerliyorum. İsterseniz siz de kullandığım bu yapıdan faydalanabilirsiniz.

Uygulama İskeletinin Oluşturulması

Bahsettiğim iskelet yapı aşağıdaki dosyalardan oluşuyor:

|-- AUTHORS
PyQT|-- CHANGELOG
|-- COPYING
|-- INSTALL
|-- MANIFEST.in
|-- README
|-- TODO
|-- data
| |-- editor
| |-- editor.desktop
| |-- editor.png
| |-- editor.qrc
| `-- editor_tr_TR.ts
|-- editor
| |-- __init__.py
| |-- main.py
| `-- mainwindow.py
|-- setup.py
`-- ui
`-- mainwindow.ui

PyQt ile yapılan açık kaynaklı uygulamalarda, Qt’yi geliştiren Nokia’nın (önceden Trolltech) belirlediği bir lisans kısıtlaması var. Buna göre açık kaynaklı bir Qt uygulaması sadece GPLv2 ya da GPLv3 lisanslı olabilir. Bu nedenle iskelet yapıda herhangi bir özgür yazılımda olması gereken dosyaları (AUTHORS, COPYING, vb.) da ekledim ve tüm geliştiricilerin anlayabilmesi için programın kodlarında ve dosya adlarında sadece İngilizce kullandım. Dosyaları bu adresten indirip istediğiniz gibi düzenleyebilirsiniz:

Şimdi, hangi dosyanın ne işe yaradığını görelim.

Ana dizindeki dosyalar

  • AUTHORS: Uygulamayı yazan kişilerin adları ve e-posta adresleri.
  • CHANGELOG: Uygulamanın hangi sürümünde nelerin değiştiğini listeleyen belge.
  • COPYING: GPLv2 veya GPLv3 lisansının tam metni.
  • INSTALL: Uygulamanın nasıl kurulması gerektiğini açıklayan metin.
  • README: Uygulamayı tanıtan ve nasıl kullanılacağını anlatan metin.
  • TODO: Uygulamada yapılması planlanan işlerin listesi.
  • setup.py: Python’un setuptools kütüphanesini kullanan bir kurulum betiği. Bu betikte PyQt uygulamaları için faydalı olabilecek bazı eklemeler yaptım. Bu eklemeler sayesinde python setup.py build komutunu verdiğinizde .ts dosyaları lrelease-qt4’ten geçerek .qm dosyasına; .qrc dosyaları pyrcc4’ten, .ui dosyaları da pyuic4’ten geçerek Python betiklerine çevriliyor ve programın dizinine konuyor Her şey otomatik olduğu için size sadece pylupdate4 komutuyla .ts dosyasını güncellemek kalıyor.
  • MANIFEST.in: setuptools ile dağıtım paketi oluşturduğumuzda dağıtımda yer alacak dosyaların listesi. python setup.py sdist --formats bztar komutunu verdiğimizde uygulamamızın tar.bz2 paketi oluşacaktır. Daha sonra paketçiler bu tar.bz2 paketini kullanarak çeşitli dağıtımlar için paket (ör. pisi) hazırlayabilirler. Ayrıca python setup.py --help komutunu vererek diğer setup komutlarını da öğrenebilirsiniz.

"data" dizinindeki dosyalar

  • editor: Programın adını taşıyan ve sadece programın ana modülündeki ana fonksiyonu çağırarak programın çalışmasını sağlayan küçük bir Python betiği. Pardus üzerinde setup.py ile kurulum yaptığınızda bu betik /usr/bin altına gidecektir.
  • editor.desktop: Programın, masaüstünüzdeki programlar menüsüne yerleşmesi için gerekli olan dosya.
  • editor.png: Programın simgesini içeren resim dosyası.
  • editor.qrc: Programın veri dosyalarının yerlerini gösteren xml dosyası. Qt Designer ile açılabilir.
  • editor_tr_TR.ts: Programın Türkiye Türkçe’sini içeren çeviri dosyası. Qt Linguist ile açılabilir.

"ui" dizinindeki dosya

  • mainwindow.ui: Programın ana penceresi. Qt Designer ile açılabilir.

"editor" dizinindeki dosyalar

  • __init__.py: Programın sürüm bilgisini ve paket adını içeren dosya. Herhangi bir Python uygulamasında from editor import main diyebilmemiz için bu dosya gereklidir.
  • mainwindow.py: Ana pencerenin sınıfını içeren dosya.
  • main.py: Programın ana fonksiyonunu içeren, çalışmasını sağlayan dosya.

PyQT_kaydet PyQT_kaydet
İskelet Programın Kurulumu ve Çalıştırılması

INSTALL dosyasında nasıl kurulup çalıştırılacağı anlatılmasına rağmen burada tekrar etmekte fayda var. Uygulamamızın çalışabilmesi için python setup.py build komutunu bir kere vermemiz gereklidir. Sonrasında python editor/main.py diyerek çalıştırmak mümkündür. Kurulum içinse python setup.py install yeterli olacaktır. Eğer KDE masaüstü kullanıyorsanız kurulumdan sonra menüdeki simgesini hemen görebilmek için kbuildsyscoca komutunu vermeniz de gerekecektir.

Kodları İnceleyelim

Bu seferki uygulamanın kodları çok uzun olduğundan dolayı burada vermeyeceğim. Dosyaların tamamını yukarıda verdiğim adresten ndirebilirsiniz. main.py dosyamızda önceki yazıda da olduğu gibi sistem yereline göre dil dosyasını yükleyen ve ana pencereyi çalıştıran kodumuz bulunuyor. Bu sefer ek olarak iki satır daha eklendiğini göreceksiniz.

import signal

Bu satırda Python’un standart kitaplıklarından signal’ı kullanacağımızı belirtiyoruz.

signal.signal(signal.SIGINT, signal.SIG_DFL)

Bu satır sayesinde konsoldan PyQt uygulamamızı çalıştırırken CTRL+C tuşlarına basarak uygulamayı sonlandırabiliyoruz. mainwindow.py ise programın ana penceresiyle ilgili her işlemin gerçekleştiği dosyamız oluyor. Burada kullanılan tüm Qt sınıfları hakkında bilgi almak için her zaman olduğu gibi Assistant’ta arama yapabilirsiniz. Şimdi bu dosyadaki önemli satırları inceleyelim.

from PyQt4 import QtGui
from ui_mainwindow import Ui_MainWindow
class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
  def __init__(self):
  QtGui.QMainWindow.__init__(self)
  self.setupUi(self)


Aslında kodun bu bölümü pencereyi işlevsiz olarak başlatmak için yeterlidir. Fakat işlevsiz bir uygulama istemediğimiz için nereye tıklandığında ne iş yapılacağını da yazıyoruz.

@QtCore.pyqtSignature("bool")
def on_action_New_triggered(self):
  if self.textChanged:
  answer = QtGui.QMessageBox.warning(
self, QtGui.QApplication.translate("MainWindow", "Warning"),
  QtGui.QApplication.translate("MainWindow", "All changes will be lost, continue?"),
  QtGui.QMessageBox.Yes|QtGui.QMessageBox.No
)
  if answer == QtGui.QMessageBox.Yes:
  self.newFile()
  else:
  self.newFile()


Buradaki ilk satır kendinden sonra gelen otomatik bağlantının sadece "bool" tipinde sinyal verildiği zaman çalışmasını sağlıyor. Yani kısacası o satır olmasaydı File>New tıklandığında alttaki kod iki kere çalışırdı diyebiliriz. Daha önceki derslerde anlatıldığı gibi, pencere sınıfı içindeki on_nesneadı_sinyaladı şeklindeki metod tanımlamaları setupUi çağırıldığı zaman otomatik olarak ilgili sinyale bağlanıyorlar. Tabi ki burada otomatik bağlantı yapmak zorunda da değiliz. Pencere sınıfının __init__ metodunda QtCore.QObject.connect(nesne, QtCore.SIGNAL("sinyaladı()"), metodadı) şeklinde bir satır ekleyerek de istediğimiz sinyalleri istediğimiz metodlara bağlayabiliriz. PyQt ve sinyaller hakkında ayrıntılı bilgi için İnternet'te arama yaparak bazı kaynaklar bulabilirsiniz.

Kod parçamızın devamında ise yazının değişip değişmediği kontrol ediliyor. Eğer yazı değişmemişse hiçbir uyarı vermeden yeni bir dosya açabiliriz fakat değişmişse yeni dosya açınca bu değişikliklerin yok olacağını söyleyip kullanıcıdan onay almalıyız. Onay alırken gördüğünüz gibi Yes ve No düğmeleri olan bir QmessageBox oluşturuluyor. Daha sonra bu ileti kutusundan gelen sonuca (answer) bakılarak yeni dosya açılma işlemi gerçekleştiriliyor.

Farkettiğiniz gibi kod parçasındaki tüm iletiler İngilizce olarak yazılmış ve QtGui.QApplication.translate fonksiyonu içine alınmış durumda. Kodları bu şekilde yazdıktan sonra pyludate4 editor/mainwindow.py editor/ ui_mainwindow.py -ts data/editor_tr_TR.ts komutuyla Türkçe dil dosyasını oluşturup bunu Qt Linguist ile açarak çevirisini yapabiliyoruz. Çeviri dosyası zaten varsa, bu komutu verdiğimizde sadece yeni eklenen ve değişen iletiler dosyaya eklenecek, önceki çevirilerimiz kaybolmayacaktır.

currentFile = QtCore.QFile(fileName)
if not currentFile.open(QtCore.QIODevice.ReadOnly|QtCore.QIODevice.Text):
self.statusBar().showMessage(QtGui.QApplication.translate("MainWindow", "Unable to open %1: %2").arg(fileName).arg(currentFile.errorString()))
else:
  self.textEdit.setPlainText(unicode(currentFile.readAll(), "utf8", "ignore"))

Dosya açan bölümdeki bu satırlarda bir metin dosyasının tek seferde UTF-8 kodlamasıyla nasıl okunabileceğini görebilirsiniz. Eğer dosya açılırken bir sorun oluşmuşsa bu sorunun ne olduğunu da yazacaktır. Kodun geri kalan kısmını keşfetmeyi size bırakıyorum. Bu keşifte Qt Assistant size her konuda yardımcı olacaktır. Bir sonraki yazıda görüşmek üzere ;).

4 yorum .

yazdır
Son güncelleme: 26 Haziran 2009