7 Mayıs 2009 Perşembe

pyqt programlama

uzun zamandır hep yazmayı düşünüp ertelediğim yazımla nihayet karşınızda olmaktan mutluyum. ben de pyqt öğrenme sürecinde sıkıntı çektim. bu nedenle mümkün olduğunda faydalı bir şey ortaya çıkarmak için uğraştım. umarım faydalı olur.

python gün geçtikçe popülerliğini artıran bir dil malumunuz. esnekliği ve kolay okunup yazılabilen söz dizimi ile öne çıkıyor. bazı özel durumlar haricinde programları bir görsel arayüz ile hazırlıyoruz. python'la birlikte çalışan bir çok farklı arayüz seti mevcut. wxpython, tkinter, pykde, pygtk ve bugünkü yazımızda inceleyeceğimiz pyqt. gelişmiş bir platform bağımsız arayüz framework'ü olan qt'nin python bağlayıcısı olan pyqt bize python kodlarıyla qt arayüz elemanlarına erişim imkanı sunuyor.

şu an qt4 versiyonu kullanılıyor. biz de örneğimizi bu versiyon üzerinden vereceğiz. şimdi gereken paketler, python, qt4, qt4 tasarımcı ve pyqt. yalnız qt'nin ve qt designer'ın eski versiyonları da paket deposunda yer alıyor. onları da yeni versiyonlarla birlikte kurarsanız uyum problemleri ve sorunlar ortaya çıkıyor. buna dikkat edelim.

qt arayüzlü python uygulama geliştirme yani pyqt çok yeni sayılabilecek bir alan. kaynak bulmak zor. internetteki çok az sayıdaki örnekler de genellikle çok basit örnekler ve ilk adımın ardından ikinci adıma geçmek sizin kendi becerinize ve çabanıza bakıyor. kendi çektiğim sıkıntıları çektirmemek için bu ilk programımızda “hello world” geleneğini bozuyoruz ve bir basamak daha ileri bir uygulamayla merhaba diyoruz.

kmenü'den uygulamalar > geliştirme > qt4 tasarımcı yoluyla arayüz tasarlama programımızı açıyoruz. daha önceden netbeans, visual studio, delphi gibi görsel bir geliştirme ortamı ile çalışmışsanız yabancılık çekmeyeceksiniz. sol tarafta parçacıkların (component) dizilmiş olduğunu görüyoruz. sağ panelde ise formumuza eklemiş olduğumuz elemanın özelliklerini ayarlayıp görebildiğimiz bir özellik düzenleyici var.

ilk açılışta nasıl bir form oluşturmak istediğimiz soruluyor. biz Main Window'u seçip oluştur diyoruz. bunun ardından boş bir pencere görüntüsü geliyor. bu pencereyi boyutlandırabilirsiniz. sağ taraftan özellik düzenleyiciden de bir çok özelliğini kurcalayıp karıştırabilirsiniz.

şimdi bu boş formumuza, sağ taraftaki parçacık menüsünde Input Widgets başlığı altından sırayla bir lineedit, bir tane de spinbox seçip sürükle-bırak yöntemiyle formumuza ekliyoruz. şimdi ise bu elemanlar arasında bir bağlantı, bir ilişki kuracağız. buna sinyal-slot ilişkisi deniyor. bu ilişkileri oluşturma ve düzenlemek için qt4 tasarımcı'da çok hoş bir özellik var. bunun f4'e basarak tasarım modundan çıkıp sinyal düzenleme moduna geçiyoruz. bu modda, fareyi bir elemanın üzerine getirdiğimizde o eleman kırmızı kırmızı renk ile belirtiliyor. sinyali gönderecek elemanın üzerine tıklayıp basılı tutarak, alıcı elmana götürüp bırakıyoruz. bunun üzerine bir pencere açılıyor

sol taraftaki metodlar (sinyal) göndericinin, sağ taraftaki metodlar (slot) ise alıcının metodları. mesela bizim örneğimizde gönderici elemanın (spinbox) valueChanged() metodu, alıcı elemanın (lineEdit) setText() metoduyla bağlantı kuruyor. tamam diyerek sinyalimizi oluşturma işlemini bitiriyoruz. ihtiyaca göre farklı metodlar kullanılabilir. sinyal işlemleri bittiğine göre sinyal düzenleme modundan varsayılan tasarım moduna geçmemiz lazım. bunun için de f3 kısayolunu kullanıyoruz. işlemler tamamlanmışsa, dosyamızı uygun bir yere kaydediyoruz.

dosyanın bulunduğu dizinde konsol açıyoruz. bunun için o klasörü açıp f4 tuşuna basmak yeterli olacaktır. ardından pyuic4 girendosya.ui -o cikacakdosya.py komutuyla .ui uzantılı dosyamızı .py uzantılı bir python dosyasına çeviriyoruz. yani pyuic4 komutu, xml tabanlı olan qt4 tasarımcı arayüz dosyasını python'un anlayabileceği bir dosya haline getirmiş oldu. şu anda Ui_MainWindow adlı bir bu arada, örneğimizde ben giriş dosyasıyla çıkış dosyasına aynı adı verdim. ama bu zorunlu değil, hatırlatayım. ayrıca yapacağımız düzenlemeleri .ui dosyasında yapacağız ve her düzenlemenin ardından yukarıdaki pyuic4 komutunu kullanarak dönüştürme işlemi yapacağız.


yeni oluşan python dosyasını açıp inceleyecek olursak, bir Ui_MainWindow sınıfı ve altında tanımlanmış setupUi ve translateUi fonksiyonlarını görebiliriz. setupUi, eleman özelliklerinin, translateUi ise elmanların yazılarının ifade edildiği metodlar. asıl önemli kısım, yeşil ile işaretlediğim satır. yani hatırlarsak, düzenleyicide oluşturmuş olduğumuz sinyal bağlantısı.

şimdi elimizde bir adet ana pencere sınıfı var. bu tek başına Hiçbir işe yaramaz. bunu işe yarar -yani çalışır- kılmak için bir çok farklı yöntem var. eğer internette pyqt konusunu inceleyecek olursanız neredeyse herkesin farklı yol izlediğini görürsünüz. ben de bu yazımda size kendi uyguladığım ve pratik bulduğum yöntemi göstermek istiyorum. bunun için diğer dosyalarla aynı dizinde bir baslat.py dosyası oluşturalım ve içini aşağıdaki dolduralım.


şimdi ilk çalışan programımızı elde etmiş olduk. buna yavaş yavaş eklemeler yaparak farklı yöntemleri örnekleyeceğiz. ama şimdi programı çalıştırmamız gerek. dosyaların bulunduğu dizinde f4'e basıp konsolu açtıktan sonra python baslat.py komutuyla programı başlatabiliriz. spinbox'tan yukarı ve aşağı ok'a basarak değeri değiştirdiğimizde lineEdit'teki değer de bununla aynı oluyor. qt4 tasarımcıda oluşturduğumuz sinyal bunu sağlıyor. şimdi qt4 tasarımcıyı açarak formumuza bir tane düğme ekleyelim. daha sonra bu düğmeyi de farklı bir yöntem için kullanacağız. düğmeyi (pushButton) parçacık seçiciden ekleyip dosyayı tekrar kaydediyoruz. pyuic4 ... komutunu tekrar vererek dönüştürme işlemini tekrarlıyoruz. şimdi de baslat.py isimli başlatıcı dosyamızı açarak bir takım eklemeler yapmamız gerekiyor.


kendimiz yazarak oluşturduğumuz yeni sinyal tanımlayıcımız aracılığıyla, düğmeye her basıldığında dosyamızın içinde harici adı altında tanımladığımız yeni fonksiyonu çalıştıracağız . bu değişiklikleri yapıp baslat.py dosyamızı kaydediyoruz. dosyaların bulunduğu dizinde f4'le konsolu açıp python baslat.py komutunu girerek programımızı çalıştırıyoruz. artık bir önceki aşamadaki özelliğe ek olarak, eklediğimiz düğmeye bastığımızda lineEdit'in yazısı “harici..” oluyor.

şimdi bir aşama daha ileri giderek farklı bir class'ın mevcut programımız içerisinde nasıl kullanılabileceğini gösteren bir örnek yapıyoruz. bunun için önce sinifDosyasi.py adıyla yeni bir python dosyası oluşturup aşağıdaki gibi dolduralım.


gördüğünüz gibi basit bir sınıfımız var. aylar dizisi, ayOku ve ayYazdir metodları var. şimdi qt4 tasarımcıyı açarak formumuza bir düğme daha ekleyip dosyayı kaydedip pyuic4.. komutuyla tekrar dönüştürelim. şimdi geriye bir tek işimiz kaldı. o da baslat.py dosyasına son şeklini vermek. hemen kolları sıvıyoruz.


baslat.py dosyasını da şekildeki gibi düzenledikten sonra tekrar konsoldan python baslat.py komutunu vererek programı çalıştırıyoruz. programımız önceki özelliklerinin yanı sıra artık ikinci düğmeye basıldığında lineEdit'e, sinif class'ından türettiğimiz ayYorumlayici nesnesinin ayYazdir metodundan gelen yazıyı yazıyor. yani spinbox'ta hangi sayı varsa, senenin o ayının adını lineEdit'te görüyoruz.


şimdi neler yaptığımızı hatırlayalım. ilk versiyonda sinyalimizi tasarımcının sinyal oluşturma moduyla kod yazmadan yapmıştık. ikinci versiyonumuzda başlatıcı dosyanın içerisinde kendi fonksiyonumuzu ve dahi sinyalimizi yazmıştık. en sonunda ise harici bir sınıfı, bu sınıftan nesne türeterek kullanıyoruz.

şimdi akla takılma ihtimali yüksek olan bir konuyu açıklamak istiyorum. anlatım karışmasın diye sona saklamıştım. kodlarımızda epey bir “self” ifadesi kullandık. gerek metotları, gerekse değişkenleri çağırırken bu takıyı kullandık. bu ne anlama geliyor? bir sınıf oluşturmuşsanız, ve bu sınıfın farklı metotları aynı değişken üzerinde işlem yapıyorsa, bu değişkeni “self.degiskenadi” şeklinde tanımlamamız ve kullanmamız gerekiyor. ayrıca eğer metotlar birbirini çağıracaksa gene aynı şekilde “self.metod()” şeklinde kullanılması gerekiyor. ancak bir fonksiyon kendi içerisinde bir değişken oluşturup kullanıyor ve değişkene bu fonksiyon dışından erişilmiyorsa başına self koymadan “değişken“ şeklinde kullanılabilir. ayrıca bir class'ın içerisinde fonksiyon oluştururken de “def fonksiyon(self, x, y):” şeklinde tanımlıyoruz. yani fonksiyon “self”i argüman olarak alıyor.

bir de unutmadan, bu pyuic4... şeklindeki konut kullanımı çok can sıkıcı olabiliyor, biliyorum. bunun için kendime yazmış olduğum bir python programcığı var. uitopy. bu sıkıcı dönüştürme işlemini kendisi otomatik yapıyor ve eğer kendisini ilk defa kullanıyorsanız o dizinde, baslat.py benzeri bir dosyayı da kendisi oluşturuyor. ilginizi çekerse http://code.google.com/p/uitopy/ adresindeki proje sayfasından kullanmak veya incelemek için indirebilirsiniz.

şimdilik bu kadar. görüşmek üzere.

1 yorum:

  1. düzeltme isteği:
    "sağ taraftaki parçacık menüsünde Input Widgets " yerine
    "sol taraftaki parçacık menüsünde Input Widgets "
    olması gerekir.
    bilgiteknik - uğurhan çakır - ugurhancakir@gmail.com

    YanıtlaSil