13
Mar

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

19
Şub

Bir önceki dersimizde qt creator’u kurmuş bir iki şeye göz gezdirmiştik. Şimdi bir uygulama yaparak bir şeyler daha öğrenelim. Bir iki not ile başlayayım işe pardus 2011 sürümünde qt creator’un son sürümü bulunuyor, elle indirip kurmanıza gerek yok, paket yöneticisinden kurabilirsiniz.

Genel Bilgiler

Biraz qt ile ilgili temel şeylerden bahsedeyim. Qt sınıfındaki her şey QObject‘ten türemiştir. Görsel şeyler(tabwidget, label), QObject’ten türemiş QWidgetlerdir. Yani bir QLabel hem qobjectin hem de qwidget’in özelliklerini barındırır.

Derleme işleminden bahsedeyim. Derleme için qmake, make kullanılır. Tabii biz qt creator kullanacağımız için derleme işlemini ctrl + r ile halledeceğiz :)

Basit Bir Örnek

Qt Creator’den File->New File or Project->Qt GUI App. -> Gerekli adımları tamamladıktan sonra yeni bir proje oluşacak.

Şimdi içeriğine bakalım: en üstte bir dizin simgesi var ve yanında projenizin adı var. Bu projeniz :) . Altında bir .pro dosyası var. Bu önceki dersimde dediğim gibi proje dosyanız, proje bilgilerini içinde tutuyor. Onun altında 2 dizin daha var. Sources ve Headers. Bunlar projelerinizin kaynak dosyaları ve başlık dosyalarının dizinleri. Sourcesin içindeki main.cpp dosyası programınızı çalıştırmaya yarayan dosyadır(önceki derse bakın.). Headers’ın içindeki mainwindow.h dosyası Sources’in içindeki mainwindow.cpp’nin başlık dosyasıdır. En altta da Forms dizini bulunmakta. Buda formlarınızın bulunduğu dizindir. Buradaki formlar .ui uzantılıdır..ui dosyaları tasarım dosyalarıdır. Qt Creator derleme yapaken bunları c++ koduna otomatik olarak çevirir.

Şimdi basit bir metin not defteri uygulaması yapalım. Ama önce:

Sinyal/Slot Olayı

Ö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. Peki neyi nasıl bağlarız:

connect(dugme, SIGNAL(clicked()), this, SLOT(close()));

Burada örnek olarak dugme’nin clicked() olayını this’in(yani formumuzun) close() olayına bağladık. Yani dugme’ye basıldığında formumuz kapanacak.

Örneğe Devam

Forms altındaki mainwindow.ui’ye çift tıklayalım ve aşağıdaki gibi bir form oluşturalım:

Bunları yaptıktan sonra Dosya Oku butonuna sağ tıklayıp -> Go to slot..’a basın. Select Signal penceresi gelecek oradan da clicked()‘a çift tıklayın. Böylece pushButtonun tıklanma olayını boş bir slota bağladık.(Üstteki anlattığım connect işlemini kendi otomatik ayarladı.) Ve bizi slotun içine yönlendirdi.

void MainWindow::on_pushButton_clicked()
{
}

Kodlarımızı bunun içine yazacağız artık.

QString str = QFileDialog::getOpenFileName(this, "Açılacak dosyayı seçin", ".", "Metin dosyaları (*.txt)");
QFile file(str);
file.open( QIODevice::ReadOnly | QIODevice::Text );
ui->plainTextEdit->setPlainText(file.readAll());
file.close();

1. satırda bir dosya açma diyaloğu gösterdik ve burdan gelecek dosya adını str’ye eşitledik. 2. satırda file adında bir QFile oluşturduk ve dosya yolunu str olarak belirledik. 3. satırda dosyamızı sadece okumak için açtık. 4. satırda plainTextEdit’e dosyanın içeriğini okuduk. 5. satırda da dosyamızı kapattık.

Çok biliyormuşum gibi bir şeyler anlatmaya çalıştım, yanlışım olmuş ise uyarırsanız, anlamadığınız yer olursa yazarsanız sevinirim. Yeni bir derste görüşmek üzere iyi günler :)

18
Şub
Evinizdeki internet bağlantısında OpenDNS servisinin filtreleme hizmetini kullanmak istiyorsanız veya sunucunuzdaki ftp, http, vnc gibi servislere ücretsiz bir alan adı üzerinden erişmek istediğinizde ip adresinizi bu servislere kayıt etmeniz gerekiyor. Ip adresiniz sabit değilse bu işi düzenli ve otomatik olarak yapacak bir araca ihtiyaç oluyor.

Aslında bu iş oldukça basit ve ddclient gibi başarılı araçlar zaten var ancak bunların bir arayüzü yok. Bu açıdan Dino'nun kullanımı oldukça kolay.

Bir başka OpenDNS hizmeti olan Dnsomatic.com servisi ise ip güncellemeye ihtiyaç duyan popüler pek çok servisteki hesaplarımıza tek tek güncelleme yapmaktan bizi kurtarıyor. Tüm bu servisleri önce dnsomatic.com hesabınıza kaydediyorsunuz, sonra dnsomatic'e tek bir güncelleme isteği gönderiyorsunuz, o sizin için kayıtlı tüm servislerinizi güncelliyor.




https://github.com/alierkanimrek/dino

http://www.ozgurlukicin.com/forum/gonullu-calismalar/20861/?page=1
17
Ara

Tubitak/UEKAE ve Çanakkale 18 Mart Üniversitesi işbirliği ile yapılan Çomak Projesinde Pardus işletim sisteminin KDE dışındaki masaüstü ortamlarını da desteklemesi amacıyla Necdet Yücel hocamızın liderliğiyle sürdürülen projemizde bazı konuların kesinleşmesi ve bir karara bağlanması için ekip olarak Tübitak'a bir ziyarette bulunduk.Ortamın güzelliği ve arkadaş canlısı Pardus ekibi bir yana projenin teknik detayları ile ilgili bazı kararlar verdik.Onur Küçük ve Gokmen Göksel ile yaptığımız fikir alışverişinden sonra GNOME, XFCE, LXDE, Enlightenment, FLUXBOX masaüstü ortamnlarının Pardus'a dahil edilmesi ve KDE altında çalışan pardus'un ürünleri olan manager ailesinin GNOME başta olmak üzere diğer masaüstü ortamlarında çalışabilmesi için verdiğimiz kararlar şunlardır:

1.

a.Çomak ekibi 2 farklı gruba ayrılacak ve gruplardan biri GNOME ve diğer masasüstü ortamlarının Pardus altında çalışmasını sağlacak ve gerekirse port edilmesi sırasında yama işlemi gerekiyorsa yama işi ile de uğraşacaklar.

b. 2. ekip ise Manager ailesinin diğer masaüstü ortamlarında da çalışmasını sağlayacaklar.

2. Kde altında çalışan hali hazırdaki managerlarımız Python programlama dilinde kodlanmış ve arayüz olarak Qt ile hazırlanmıştır.Gnome altında da Python ve Qt ikilisini kullanacağız.

3. Belki de yol haritamızı ve takvimimizi belirgin kılan en önemli karar Manager ailesinin GNOME,XFCE ,LXDE, Enlightenment,FLUXBOX gibi diğer masaüstü ortamlarına taşırken hangi arayüz kütüphanesini kullanacağımızdı.Gnome ve diğer masaüstü ortamlarına taşırken yine Python ve Qt ikilisini kullanacağız Bunun sebeplerini de sıralamak gerekirse:

a.Çomak projesinin uzun vade de sürdürülebilirlik açısından Qt ile geliştirilmesi

b.Qt'nin mükemmel seviyede olan belgelendirmesi ve Qt geliştiricilerin sayısının fazlalığı

c.QT'nin nesneye yönelik tasarımı Python tarafında bu yapının çok iyi kullanılabilmesi ve daha bir çok neden bizi Qt ve Python ikilisine itti.Ayrıntı için

4.Pardus de onemli işleri yerine getiren pisi,comar gibi modullere yeni bir tane daha ekleyebiliriz.Oluşturacağımız bu modul KDE dışındaki masaüstü ortamlarına gore şekil alacak şekilde tasarlanacak bir nevi adapter olacak.

Toplantı da alınan kararlar genel itibariyle bu şekilde idi.Çomak Ekibi olarak ilerleyen günlerde Necdet Yücel hocamız bir takvim yayınlacak.

19
Eki

Birçok konuda bu tip tartışmalar yaşanır, bazen sadece fanatiklik bile bir tarafın seçilmesinde etken olabilir (doğru olmayabilir ama olur). Ben bunun dışında biraz gerçeklerden bahsetmek istiyorum:

  • Özellik Kümesi
    • Qt sağladıkları ile birlikte tam bir geliştirme kütüphanesi, sadece grafik arabirim için değil en alt seviyede ihtiyaçlar için bile bir destek sunuyor. Veritabanı, Ağ, Web, XML … uzayıp giden kocaman bir özellik kümesini sunuyor. Öyle ki sadece Qt kullanarak koskoca bir masaüstü ortamı yazmak mümkün. Tam olarak neler içerdiğine [1] adresinden bakılabilir.
    • GTK+ ise Qt’ye göre çok daha az sayılabilecek bir özellik listesine sahip, fakat bu noktada GTK+’ın geliştirilmesindeki asıl sebebin arabirimler olduğu unutulmamalı. Arabirim dışında kalan işler için gerekli özellikler GLib altında geliştiriliyor (GTK+, Glib üzerinde), Qt’nin sunduğu kadar geniş bir yelpazeye sahip olmasa da yeterince uzun bir özellik kümesi var. Daha detaylı bir liste API dokümanlarından [2] incelenebilir.
    • Qt C++ ‘a ek olarak kolayca anlaşılabilecek sinyal slot mekanizmasını beraberinde getiriyor, GTK+ ise C üzerinde nesneye dayalı bir yaklaşım sergilemeye çalışırken anlaşılması zor bir hale geliyor.
  • Görünüm
    • Qt Native QT uygulamaları, QGtkStyle[3] ile birlikte GTK+ temalarını (simge temaları dahil) kullanabilir hale geliyor, bunun dışında Qt Windows ve Mac Os X üzerinde de doğal görünüm sağlayabilen ortak tek kütüphane. QGtkStyle Qt tarafından sağlanıyor.
    • GTK+ Sadece kendi tema stillerini destekliyor, GTK-Qt-Engine [4] ile (GTK dışında geliştirilen gönüllü bir çalışma) bütün Qt temalarının desteklenmesi söz konusu olamıyor. Windows ve Mac Os X için herhangi bir desteği yok, kendi temaları ile çalışmaya devam ediyor. Ayrıca tema noktasında iş sadece görsellik ile bitmiyor, butonların sıralaması, layout düzeni gibi işler de temaya bağımlı olarak değişebiliyor (Qt’de İptal en sağ altta, GTK+’da Tamam en sağ altta gibi) QGtkStyle bu farklılıkları gözetebiliyor, GTK-Qt-Engine’in böyle bir yeteneği yok.
    • Ayrıca tema noktasında iş sadece görsellik ile bitmiyor, butonların sıralaması, layout düzeni gibi işler de temaya bağımlı olarak değişebiliyor (Qt’de İptal en sağ altta, GTK+’da Tamam en sağ altta gibi) QGtkStyle bu farklılıkları gözetebiliyor, GTK-Qt-Engine’in böyle bir yeteneği yok.
  • Altyapı
    • Qt C++ ile geliştirilmiş ve C++ ile tam uyumlu bir API sunuyor. Nesneye Dayalı bir dilin bütün nimetlerinden faydalanıyorlar (bütün objeler QObject nesnesinden, bütün grafik arabirim nesneleri QObject nesnesinden türemiş QWidget nesnesinden türüyor, …)
    • GTK+ Qt’nin aksine C ile yazılmış ve kendine has bir API yapısına sahip. Fakat C++ için yazılmış bir wrapper ile (GTKmm) Qt’nin sahip olduğuna benzer bir hiyerarşi düzenine sahip. GTK+ nesneye dayalı bir yapı için, GObject nesnesinden miras alarak türüyor.
  • Belgelendirme
    • Qt eksiksiz bir API belgesi ve bunu yanında süreçleri profesyonelce yazılmış bir bilişim kitabı tadında anlatan nasıl yapılır belgelerine sahip. Bu belgeler Qt tarafından sağlanıyor ve Qt paketleri ile birlikte erişilebilen Asisstant adlı uygulama ile ya da web üzerinden sunuluyor. Aynı zamanda Qt uygulamaları için doxygen formatında yazılmış açıklama metinlerinen QHelpEngine ile yardım belgesi üretmek mümkün hale geliyor.
    • GTK+ ‘da Qt’de olduğu gibi detaylı bir belgelendirme arşivine sahip değil, API belgeleri GTK tarafından çevrim içi sunuluyor olsa da, çevrim dışı belgelere 3.parti yazılımlar ile erişebiliyorsunuz.
  • Tasarım Araçları
    • Qt Designer adından bir arabirim tasarımcısı ile birlikte geliyor, bu tasarımcı aynı zamanda Qt Creator uygulaması içine gömülü bir şekilde çalışarak tam bir geliştirme ortamı sunuyor. Designer XML tabanlı bir tasarım dosyası üretiyor ve bu dosya hazır araçlar sayesinde desteklenen diller için hazırlanmış kodlar haline getiriliyor. Ayrıca designer mevcut Qt nesneleri dışında dışarıdan geliştirmiş olduğunuz nesnelerin de arabirimi üzerinden kullanılmasına olanak sağlıyor.
    • GTK+ Glade ile birlikte arabirim tasarımı işini hallediyor, Glade GtkBuilder formatında Qt’dekine benzer bir şekilde desteklenen dillere çevirilebilecek bir tasarım dosyası üretiyor, bu dosyalar yine benzer araçlar ile desteklenen diller için üretiliyor.
  • Performans
    • Bu konuda net bir sonuç ortaya koymak pek mümkün olmuyor, bu süreci alt kümelerine; çizim, bellek yönetimi, yüklenme süresi, çözülme süresi vs. şeklinde bölerek değerlendirmek gerek. Zira Qt yapılan iş ile ilgili bir çok bileşeni kendi sağlıyor olsa da GTK+ ile dışarıdan bir çok bileşeni kullanmak gerekiyor. Bu noktada performans değerlendirmesini net bir biçimde yapmak çok zor bir hale geliyor.
    • Genel kanı GTK+’ın Qt’ye göre daha hafif olduğu olsa da Qt’nin özellikle 4.4 sürümünden sonra bellek yönetimi ile ilgili yapmış olduğu yenilikler ile bu durumun geçerliliğini yitirdiği gözleniyor.
    • Daha önce yapılmış polygon çizimleri ile ilgili bir performans testini [5] adresinde bulabilirsiniz.
  • Çeviriler
    • Qt kendi çeviri yönetim sistemine sahip fakat Gettext kütüphaneleri ile birlikte de kullanılabiliyor. Bütün Qt nesneleri Unicode destekliyor ve soldan-sağa <> sağdan-sola diller arası geçiş için bütün arabirim otomatik olarak yön değiştirebiliyor.
    • GTK+ herhangi bir çeviri yönetim sistemine sahip değil fakat Gettext kullanılarak çevirilebilir arabirimler tasarlamak mümkün.
  • Test
    • Qt Arabirim ya da arabirimden bağımsız süreçlerin birim testlerini yapabilmek için bir test kütüphanesi sunuyor (QTestLib)
    • GTK+ için böyle bir özellik mevcut değil
  • Programlama Dilleri
    • Qt C++ ile geliştiriliyor ve doğal hali ile C++ destekliyor. Bunun yanı sıra Qt için hemen hemen bütün dillerde kullanılmak üzere bağlayıcılar (binding) geliştirilmiş. Ayrıca Qt ECMA script (JavaScript) destekliyor. Ayrıca kendine has QML adında hızlıca uygulama geliştirebileceğiniz bir platform daha sunuyor.
    • GTK+ C desteği ile geliyor fakat Qt’de olduğu birçok bağlayıcı GTK+ için de mevcut. Bağlayıcılar konusunda Qt’den hemen hemen bir eksiği olmamasına rağmen, GTK+ ile JavaScript şimdilerde mümkün gözükmüyor.
  • Çokluortam
    • Qt çokluortam işlerini Phonon ile hallediyor (Qt’nin içerisinden geliyor) birçok arkaucu (backend) destekliyor; mplayer, vlc, gstreamer, xine. Phonon arka uçlar için ortak kulanılacak bir katman, arka uçlar sisteme göre değişiyor ve bu arka uçlar Qt tarafından değil, çalıştığı sistem tarafından sağlanıyor. Ayrıca çokluortam dosyaları üzerinde (efekt ekleme gibi) işlem yapmaya da olanak sağlıyor.
    • GTK+ Gstreamer kullanıyor ve arka uç olarak sadece Gstreamer’ı destekliyor. Arka uç Gstreamer’ın kendisi GTK+ tarafından sağlanıyor.
  • İletişim Desteği
    • Qt Dbus ve IPC destekliyor
    • GTK+ sadece Dbus destekliyor
  • Lisans
    • Belki de bu tartışmanın eskiden kullanılan en önemli vurgusu Qt’nin lisans durumydu, fakat Nokia satın aldıktan sonra Qt’nin lisansını LGPL olarak değiştirdi, bu noktada GTK+ ile Qt arasında özgürlük açısından herhangi bir fark bulunmuyor fakat Qt için ücreti karşılığında profesyonel destek alabiliyorken GTK+ için hala böyle bir destek alamıyorsunuz.
    • Ayrıca işin Python tarafında Qt’nin LGPL olmasının ardından pyGtk düşüşe geçmiş.

Sonuç

Açıkçası bu listeyi çok daha fazla uzatmak mümkün. Bir yerde durmak gerekiyordu :).

Benim kişisel görüşüm Qt’den yana; size tam bir çözüm sunuyor ve bu tam çözümü sunarken her süreç birbirine benzer işliyor, Qt içeren bir C++ kodunu çok hızlı bir şekilde Qt içeren bir Python kodu haline getirebiliyorsunuz. Nesneye dayalı geliştirilmiş olmasının verdiği esneklik ve uyum, üstüne bir de çok detaylı belgelendirme, rahat okunabilir kodlar eklenince Qt açık ara lider benim için fakat ikisi ile de mükemmel uygulamalar geliştirmek mümkün.

Bu konu ile ilgili yaptığım araştırma sırasında karşılaştığım/kaynak aldığım bazı yazılara [6] [7] [8] [9] adreslerinden ulaşılabilir.

Not: GTK+ ile ilgili yazdıklarımda eksiklerim/yanlışlarım olabilir, kesinlikle bu konuda yorum bırakmaktan çekinmeyin.

[1] http://doc.qt.nokia.com/4.7/classes.html
[2] http://library.gnome.org/devel/references#api-platform
[3] http://labs.qt.nokia.com/2008/05/13/introducing-qgtkstyle/
[4] http://kde-look.org/content/show.php?content=9714
[5] http://zrusin.blogspot.com/2006/10/benchmarks.html
[6] http://techfreaks4u.com/blog/?p=953
[7] http://ldn.linuxfoundation.org/article/application-development-framework-choices-gtk-vs-qt
[8] http://www.jbkempf.com/blog/post/2007/02/10/Qt4-Interface
[9] http://www.caddd.org/2010/03/qt-vs-gtk.html

29
Eyl
"Service Manager" kodlarını incelemeye koyulmadan önce yapmam gereken Qt yi anlamaktı. Bu sadece "Service Manager" kodları için değil projenin tamamı için bana lazım olan şey. Bunun için "Qt4 ile C++ Gui programlama" (C++ GUI Programming with Qt4) adlı GPL lisanslı kitabı okumaya başladım. Çalıştığım ve anladığım kısımlar özet olarak şöyle:

Merhaba Qt

1. #include QApplication
2. #include QLabel
3.
4. int main(int argc, char *argv[])
5. {
6. QApplication app(argc,argv);
7. QLabel *label= new QLabel("Hello Qt!");
8. label-> show();
9. return app.exec();
10.
11. }

1. ve 2. satırlarda QApplication ve QLabel sınıfları dahil ediliyor. QApplication sınıfı uygulamayı yönetmek için kullanılıyor. QLabel sınıfı "Hello Qt!" yazdıracak olan "widget"i oluşturmamızı sağlıyor.

8.satır ekrana çıktı veren fonksiyonun çağrıldığı kısım.
9. ise uygulama kontrolü Qt ye geçer ve uygulama bir olay döngüsü içine girer.

Olay Döngüsü (event loop): Programın bir kullanıcı eylemi (fare tıklaması veya bir tuşa basmak gibi) için beklediği bir tür bekleme modudur.

Bağlantılar Kurma

Kitapta şöyle bir örnek yer alıyor: Kullanıcının "Quit" tuşuna bastığında programdan çıkan bir pencere...

Burada bir kullanıcı girdisi bekleme durumu var. Bunun için bağlantı kurmak gerekir.

Bunu şöyle yapıyoruz:
1 #include QApplication
2 #include QPushButton
3 int main(int argc, char *argv[])
4 {
5 QApplication app(argc, argv);
6 QPushButton *button = new QPushButton("Quit");
7 QObject::connect(button, SIGNAL(clicked()), &app, SLOT(quit()));
8 button->show();
9 return app.exec();
10 }

Öncelikle bir önceki örnekten farklı olarak QPushButton sınıfından buton örneği oluşturuluyor. Bu butonu QObject sınıfının connect() metoduyla butona tıklandığında quit() metodunu çağırması sağlanıyor.
SIGNAL() : Kullanıcıdan beklenen olay.
SLOT() : Bu olay karşısında verilecek tepki.

Widgetleri Yerleştirme

Bunun için kullanıcıya yaşını soran ve kullanıcının yaşını girebilmesi için bir spinbox ve bir slider sağlayan bir uygulama örneği var kitapta.
Birden fazla Widget'i bir pencerede gösterebilmek yerleşimlerini ayarlamak için Layoutlar kullanılır.
#include QApplication
#include QHBoxLayout
#include QSlider
#include QSpinBox

int main(int argc, char *argv[])
{

QApplication app(argc, argv); /*Uygulamayı yönetmek için oluşturuluyor.

QWidget *window = new QWidget; /* Yeni bir pencere
window->setWindowTitle("Enter Your Age"); /* Pencerenin başlığı

QSpinBox *spinBox = new QSpinBox; /* Spinbox örneği oluşturuluyor
QSlider *slider = new QSlider(Qt::Horizontal); /* Slider örneği

spinBox->setRange(0, 130); /* Spinbox yapılandırması
slider->setRange(0, 130); /* Slider yapılandırması

/*Bağlantı kurulumu*/
QObject::connect(spinBox, SIGNAL(valueChanged(int)),slider, SLOT(setValue(int)));
QObject::connect(slider, SIGNAL(valueChanged(int)),spinBox, SLOT(setValue(int)));
spinBox->setValue(35); /*Spinbox 'a öntanımlı değer verme*/

/*Widgetleri Yerleştirme*/
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(spinBox);
layout->addWidget(slider);
window->setLayout(layout);

/*Göster*/
window->show();

/*Olay döngüsü*/
return app.exec();
}

QHBoxLayout kütüphanesi widgetleri yerleştirmemize imkan verir. QSlider slider, QSpinbox ise spinbox oluşturmaya yarar.

Widgetlerin yerleşimiyle ilgili üç ana sınıf:
  • QHBoxLayout : Parçacıkları horizontal olarak soldan sağa doğru yerleştirir.
  • QVBoxLayout : Parçacıkları düşey olarak üstten aşağıya doğru sıralar.
  • QGridLayout: Parçacıkları bir ızgaraya yerleştirir.

Diyalog Oluşturma
Diyalog : Kullanıcı ile programın iletişim kurmasını sağlar. Bir diyalog örneği:
Bu örnekte kodlar finddialog.h ve finddialog.cpp dosyalarından oluşuyor. Bunun sebebi diyaloğu bir sınıfla meydana getirmek. Böylece kendi signal ve slot ları olan bağımsız bir bileşen olacak.

finddialog.h

#ifndef FINDDIALOG_H
#define FINDDIALOG_H
#include QDialog

class QCheckBox; /*seçim kutusu oluşturmak için sınıf*/
class QLabel; /*kullanıcıya bir şeyler söylemek için Label */
class QLineEdit; /*kullanıcının bize bir şeyler söylemesi için yazı kutucuğu*/
class QPushButton; /*tıklamak için buton*/

class FindDialog : public QDialog /* FindDialog sınıfı QDialog sınıfından türetilir.*/
{
Q_OBJECT
/*Q_OBJECT: sinyaller ve slotların bulunduğu tüm sınıflarda bulunması gereken makro*/

public:
FindDialog(QWidget *parent = 0);
/*parent parametresi sınıfın , türetildiği sınıfı gösterir. Varsayılan değeri "null"dır.*/

signals:
void findNext(const QString &str, Qt::CaseSensitivity cs); /*ileri sinyali*/
void findPrevious(const QString &str, Qt::CaseSensitivity cs);/*geri sinyali*/

private slots: /*yuvaların tanımlanması*/
void findClicked();
void enableFindButton(const QString &text);
private:
/*Burada sınıf tanımlamalarını önce yaptık. Bunu yaparken işaretçi kullandık. Böylece derleme işinin daha kolay olması sağlanmış oldu.*/
QLabel *label;
QLineEdit *lineEdit;
QCheckBox *caseCheckBox;
QCheckBox *backwardCheckBox;
QPushButton *findButton;
QPushButton *closeButton;
};
#endif

Şimdi sıra *.h uzantılı dosyanın import edileceği koda geldi. Burada tanımladığımız sınıfları, makroları (signal, slot) kullanıyoruz.
finddialog.cpp

#include QtGui /*Qt arayüz kitaplığı. Bu kitaplık QtGui ve QtCore modüllerinin parçası olan tüm sınıfların tanımlarını içerir. Bunu başta import etmek bizi her sınıf için ayrı ayrı dahil etme sıkıntısından kurtarır.*/

#include "finddialog.h" /*Bizim tanımladığımız kütüphane */

FindDialog::FindDialog(QWidget *parent): QDialog(parent) /*Sınıfın yapıcısına parent parametresini girerek çocuk widgetler oluşturulur.*/
{
label = new QLabel(tr("Find &what:")); /*tr() fonksiyonu içene aldığı cümleyi başka dillere çevirmek için kullanılır. Ampersan işareti kısayol tanımlamak için kullanılır. Alt+ W ye basıldığı zaman what kelimesinin üstü işaretlenecektir.*/
lineEdit = new QLineEdit;
label->setBuddy(lineEdit); /*setBuddy fonksiyonu da aynı işi yapmaktadır.*/
/*Check box oluşturuluyor*/
caseCheckBox = new QCheckBox(tr("Match &case"));
backwardCheckBox = new QCheckBox(tr("Search &backward"));
/*find butonu oluşturuluyor.*/
findButton = new QPushButton(tr("&Find"));
findButton->setDefault(true);
findButton->setEnabled(false);
/*kapama tuşu*/
closeButton = new QPushButton(tr("Close"));

connect(lineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(enableFindButton(const QString &))); /*metin düzenleyicideki metin değiştiği zaman enabeFindButton fonksiyonu çağırılır.*/
connect(findButton, SIGNAL(clicked()),this, SLOT(findClicked())); /*find butonuna tıklandığında findClicked() fonksiyonu çağırılır.*/
connect(closeButton, SIGNAL(clicked()),this, SLOT(close())); /*close butonuna tıklandığında close() fonksiyonu çağırılır.*/

/*label ve lineedit parçacıklarının soldan sağa yerleştirilmesi*/

QHBoxLayout *topLeftLayout = new QHBoxLayout;
topLeftLayout->addWidget(label);
topLeftLayout->addWidget(lineEdit);

/*checkboxlar ve yukarıdaki topLeftLayout'un sol tarafta yukarıdan aşağıya yerleştirilmesi */
QVBoxLayout *leftLayout = new QVBoxLayout;
leftLayout->addLayout(topLeftLayout);
leftLayout->addWidget(caseCheckBox);
leftLayout->addWidget(backwardCheckBox);

/*butonların sağ tarafta yukarıdan aşağıya yerleştirilmesi*/

QVBoxLayout *rightLayout = new QVBoxLayout;
rightLayout->addWidget(findButton);
rightLayout->addWidget(closeButton);
rightLayout->addStretch();
/*sol taraf ile sağ tarafın soldan sağa hizalanması*/
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addLayout(leftLayout);
mainLayout->addLayout(rightLayout);
setLayout(mainLayout);

setWindowTitle(tr("Find"));/*pencerenin başında gösterilecek metin düzenleniyor.*/
setFixedHeight(sizeHint().height()); /*parçacıkları ideal boyutlarına getiriyor.*/
}
void FindDialog::findClicked() /*find butonuna tıklandığında yapılacak olan işler*/
{
QString text = lineEdit->text(); /*metin düzenleyiciye yazılan yazılar text değişkenine atanıyor.*/
Qt::CaseSensitivity cs =caseCheckBox->isChecked() ? Qt::CaseSensitive
:Qt::CaseInsensitive;
if (backwardCheckBox->isChecked()) {
emit findPrevious(text, cs); /*emit anahtar kelimesi Qt'ye özeldir. Dışa aktarmak anlamına gelir.*/
} else {
emit findNext(text, cs);
}
}

void FindDialog::enableFindButton(const QString &text)/*bu fonksiyon düzenleyiciye bir şeyler yazıldığı zaman çağrılır. Find butonunu seçilir kılar.*/
{
findButton->setEnabled(!text.isEmpty());
}

Şimdi de FindDialog parçacığını test etmek için main.cpp dosyasını oluşturuyoruz.

#include QApplication
#include "finddialog.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
FindDialog *dialog = new FindDialog;
dialog->show();
return app.exec();
}
26
Eyl
"Service Manager" kodlarını incelemeye koyulmadan önce yapmam gereken Qt yi anlamaktı. Bu sadece "Service Manager" kodları için değil projenin tamamı için bana lazım olan şey. Bunun için "Qt4 ile C++ Gui programlama" (C++ GUI Programming with Qt4) adlı GPL lisanslı kitabı okumaya başladım. Çalıştığım ve anladığım kısımlar özet olarak şöyle:

Merhaba Qt

1. #include
2. #include
3.
4. int main(int argc, char *argv[])
5. {
6. QApplication app(argc,argv);
7. QLabel *label= new QLabel("Hello Qt!");
8. label-> show();
9. return app.exec();
10.
11. }

1. ve 2. satırlarda QApplication ve QLabel sınıfları dahil ediliyor. QApplication sınıfı uygulamayı yönetmek için kullanılıyor. QLabel sınıfı "Hello Qt!" yazdıracak olan "widget"i oluşturmamızı sağlıyor.

8.satır ekrana çıktı veren fonksiyonun çağrıldığı kısım.
9. ise uygulama kontrolü Qt ye geçer ve uygulama bir olay döngüsü içine girer.

Olay Döngüsü (event loop): Programın bir kullanıcı eylemi (fare tıklaması veya bir tuşa basmak gibi) için beklediği bir tür bekleme modudur.

Bağlantılar Kurma

Kitapta şöyle bir örnek yer alıyor: Kullanıcının "Quit" tuşuna bastığında programdan çıkan bir pencere...

Burada bir kullanıcı girdisi bekleme durumu var. Bunun için bağlantı kurmak gerekir.

Bunu şöyle yapıyoruz:
1 #include
2 #include
3 int main(int argc, char *argv[])
4 {
5 QApplication app(argc, argv);
6 QPushButton *button = new QPushButton("Quit");
7 QObject::connect(button, SIGNAL(clicked()), &app, SLOT(quit()));
8 button->show();
9 return app.exec();
10 }

Öncelikle bir önceki örnekten farklı olarak QPushButton sınıfından buton örneği oluşturuluyor. Bu butonu QObject sınıfının connect() metoduyla butona tıklandığında quit() metodunu çağırması sağlanıyor.
SIGNAL() : Kullanıcıdan beklenen olay.
SLOT() : Bu olay karşısında verilecek tepki.

Widgetleri Yerleştirme

Bunun için kullanıcıya yaşını soran ve kullanıcının yaşını girebilmesi için bir spinbox ve bir slider sağlayan bir uygulama örneği var kitapta.
Birden fazla Widget'i bir pencerede gösterebilmek yerleşimlerini ayarlamak için Layoutlar kullanılır.
#include
#include
#include
#include

int main(int argc, char *argv[])
{

QApplication app(argc, argv); /*Uygulamayı yönetmek için oluşturuluyor.

QWidget *window = new QWidget; /* Yeni bir pencere
window->setWindowTitle("Enter Your Age"); /* Pencerenin başlığı

QSpinBox *spinBox = new QSpinBox; /* Spinbox örneği oluşturuluyor
QSlider *slider = new QSlider(Qt::Horizontal); /* Slider örneği

spinBox->setRange(0, 130); /* Spinbox yapılandırması
slider->setRange(0, 130); /* Slider yapılandırması

/*Bağlantı kurulumu*/
QObject::connect(spinBox, SIGNAL(valueChanged(int)),slider, SLOT(setValue(int)));
QObject::connect(slider, SIGNAL(valueChanged(int)),spinBox, SLOT(setValue(int)));
spinBox->setValue(35); /*Spinbox 'a öntanımlı değer verme*/

/*Widgetleri Yerleştirme*/
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(spinBox);
layout->addWidget(slider);
window->setLayout(layout);

/*Göster*/
window->show();

/*Olay döngüsü*/
return app.exec();
}

QHBoxLayout kütüphanesi widgetleri yerleştirmemize imkan verir. QSlider slider, QSpinbox ise spinbox oluşturmaya yarar.

Widgetlerin yerleşimiyle ilgili üç ana sınıf:
  • QHBoxLayout : Parçacıkları horizontal olarak soldan sağa doğru yerleştirir.
  • QVBoxLayout : Parçacıkları düşey olarak üstten aşağıya doğru sıralar.
  • QGridLayout: Parçacıkları bir ızgaraya yerleştirir.

Diyalog Oluşturma
Diyalog : Kullanıcı ile programın iletişim kurmasını sağlar. Bir diyalog örneği:
Bu örnekte kodlar finddialog.h ve finddialog.cpp dosyalarından oluşuyor. Bunun sebebi diyaloğu bir sınıfla meydana getirmek. Böylece kendi signal ve slot ları olan bağımsız bir bileşen olacak.

finddialog.h

#ifndef FINDDIALOG_H
#define FINDDIALOG_H
#include

class QCheckBox; /*seçim kutusu oluşturmak için sınıf*/
class QLabel; /*kullanıcıya bir şeyler söylemek için Label */
class QLineEdit; /*kullanıcının bize bir şeyler söylemesi için yazı kutucuğu*/
class QPushButton; /*tıklamak için buton*/

class FindDialog : public QDialog /* FindDialog sınıfı QDialog sınıfından türetilir.*/
{
Q_OBJECT
/*Q_OBJECT: sinyaller ve slotların bulunduğu tüm sınıflarda bulunması gereken makro*/

public:
FindDialog(QWidget *parent = 0);
/*parent parametresi sınıfın , türetildiği sınıfı gösterir. Varsayılan değeri "null"dır.*/

signals:
void findNext(const QString &str, Qt::CaseSensitivity cs); /*ileri sinyali*/
void findPrevious(const QString &str, Qt::CaseSensitivity cs);/*geri sinyali*/

private slots: /*yuvaların tanımlanması*/
void findClicked();
void enableFindButton(const QString &text);
private:
/*Burada sınıf tanımlamalarını önce yaptık. Bunu yaparken işaretçi kullandık. Böylece derleme işinin daha kolay olması sağlanmış oldu.*/
QLabel *label;
QLineEdit *lineEdit;
QCheckBox *caseCheckBox;
QCheckBox *backwardCheckBox;
QPushButton *findButton;
QPushButton *closeButton;
};
#endif

Şimdi sıra *.h uzantılı dosyanın import edileceği koda geldi. Burada tanımladığımız sınıfları, makroları (signal, slot) kullanıyoruz.
finddialog.cpp

#include /*Qt arayüz kitaplığı. Bu kitaplık QtGui ve QtCore modüllerinin parçası olan tüm sınıfların tanımlarını içerir. Bunu başta import etmek bizi her sınıf için ayrı ayrı dahil etme sıkıntısından kurtarır.*/

#include "finddialog.h" /*Bizim tanımladığımız kütüphane */

FindDialog::FindDialog(QWidget *parent): QDialog(parent) /*Sınıfın yapıcısına parent parametresini girerek çocuk widgetler oluşturulur.*/
{
label = new QLabel(tr("Find &what:")); /*tr() fonksiyonu içene aldığı cümleyi başka dillere çevirmek için kullanılır. Ampersan işareti kısayol tanımlamak için kullanılır. Alt+ W ye basıldığı zaman what kelimesinin üstü işaretlenecektir.*/
lineEdit = new QLineEdit;
label->setBuddy(lineEdit); /*setBuddy fonksiyonu da aynı işi yapmaktadır.*/
/*Check box oluşturuluyor*/
caseCheckBox = new QCheckBox(tr("Match &case"));
backwardCheckBox = new QCheckBox(tr("Search &backward"));
/*find butonu oluşturuluyor.*/
findButton = new QPushButton(tr("&Find"));
findButton->setDefault(true);
findButton->setEnabled(false);
/*kapama tuşu*/
closeButton = new QPushButton(tr("Close"));

connect(lineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(enableFindButton(const QString &))); /*metin düzenleyicideki metin değiştiği zaman enabeFindButton fonksiyonu çağırılır.*/
connect(findButton, SIGNAL(clicked()),this, SLOT(findClicked())); /*find butonuna tıklandığında findClicked() fonksiyonu çağırılır.*/
connect(closeButton, SIGNAL(clicked()),this, SLOT(close())); /*close butonuna tıklandığında close() fonksiyonu çağırılır.*/

/*label ve lineedit parçacıklarının soldan sağa yerleştirilmesi*/

QHBoxLayout *topLeftLayout = new QHBoxLayout;
topLeftLayout->addWidget(label);
topLeftLayout->addWidget(lineEdit);

/*checkboxlar ve yukarıdaki topLeftLayout'un sol tarafta yukarıdan aşağıya yerleştirilmesi */
QVBoxLayout *leftLayout = new QVBoxLayout;
leftLayout->addLayout(topLeftLayout);
leftLayout->addWidget(caseCheckBox);
leftLayout->addWidget(backwardCheckBox);

/*butonların sağ tarafta yukarıdan aşağıya yerleştirilmesi*/

QVBoxLayout *rightLayout = new QVBoxLayout;
rightLayout->addWidget(findButton);
rightLayout->addWidget(closeButton);
rightLayout->addStretch();
/*sol taraf ile sağ tarafın soldan sağa hizalanması*/
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addLayout(leftLayout);
mainLayout->addLayout(rightLayout);
setLayout(mainLayout);

setWindowTitle(tr("Find"));/*pencerenin başında gösterilecek metin düzenleniyor.*/
setFixedHeight(sizeHint().height()); /*parçacıkları ideal boyutlarına getiriyor.*/
}
void FindDialog::findClicked() /*find butonuna tıklandığında yapılacak olan işler*/
{
QString text = lineEdit->text(); /*metin düzenleyiciye yazılan yazılar text değişkenine atanıyor.*/
Qt::CaseSensitivity cs =caseCheckBox->isChecked() ? Qt::CaseSensitive
:Qt::CaseInsensitive;
if (backwardCheckBox->isChecked()) {
emit findPrevious(text, cs); /*emit anahtar kelimesi Qt'ye özeldir. Dışa aktarmak anlamına gelir.*/
} else {
emit findNext(text, cs);
}
}

void FindDialog::enableFindButton(const QString &text)/*bu fonksiyon düzenleyiciye bir şeyler yazıldığı zaman çağrılır. Find butonunu seçilir kılar.*/
{
findButton->setEnabled(!text.isEmpty());
}

Şimdi de FindDialog parçacığını test etmek için main.cpp dosyasını oluşturuyoruz.

#include
#include "finddialog.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
FindDialog *dialog = new FindDialog;
dialog->show();
return app.exec();
}

18
Mar


Dün QtTürkiye listesine gelen bir mesajı buradan paylaşayım istedim. Sahalarda görmek istediğimiz hareketler bunlar:

> Merhaba arkadaşlar,
> Yaklaşık bir yıldır bu gruba üyeyim. Sorulan sorulara hemen cevap
> verilmesi gerçekten takdire değer. Yine yaklaşık bir yıl önce ben de
> Qt'a merak saldım. Ancak yeterli Türkçe kaynak olmadığını düşünerek
> bahsi geçen kitabı çevirmeye koyuldum. Ve nihayet 12 bölümün
> çevirisinden oluşan bir dokümanı yayınladım. Dokümanı http://www.qtturk.tk
> adresinden indirebilirsiniz. Yeni başlayanlar için yararlı bir kaynak
> olmasını umuyorum.
>
> İyi çalışmalar.
>
> Ufuk Uzun,
> Sakarya Üniversitesi -
> Bilgisayar Mühendisliği(2. Sınıf)
30
Kas
Pek çoğumuz OpenDNS'i bazı sansürlü siteleri açmak için kullanılan basit bir DNS servisi olarak biliyor, gerçekte ise üyelerine dns sunucusu üzerinden ücretsiz içerik filtreleme hizmeti veren bir servis. Eğer Pardus'ta internet içerik filtreleme kullanmak istiyorsanız bugün için en basit çözüm OpenDNS servisini kullanmak. (Tabii bu sözüm squid+dansguardian gibi paketleri yönetebilecek seviyedeki kullanıcılar için geçerli değil.)

Pardus'ta OpenDNS servisini filtreleme amaçlı kullanabilmek için OpenDNS'in ağınızın WAN ip adresini bilmesi gerekiyor. Bu iş aslında çok basit, kuracağınız küçük bir betik bu adresi belirli aralıklarla OpenDNS'e bildiriyor, bunun nasıl yapıldığını anlatan bir yazı zaten uzun zamandır özgürlükiçin'de var.

Ancak gördükleri $ işareti her şeyi GUI aracılığı ile yapmaya alışkın kullanıcıları koşarak uzaklaştırmaya yetiyor. Bende bir süredir bu küçük işlemleri nasıl bir GUI'ye yerleştiririm diye düşünüyordum. Bayram tatili fırsat oldu.

Konuyu araştırırken OpenDNS'in aslında çok basit bir API kullandığını ve bir https çağrısı ile adresin güncellenebildiğini öğrendim. Bununla ilgili python örneklerini de bulunca kendi güncelleme istemcimi yazarım dedim ve işe koyuldum.

Pog adını verdiğim (belki adını değiştiririm, böyle garip isimleri nereden buluyorsun demeyin kısaltma işte) küçük program tamamlandığında çok sevdiğimiz GUI aracılığı ile girdiğiniz OpenDNS kullanıcı adı ve şifresi ile cron zamanlayıcısını kullanarak belirli aralıklarla güncellemeyi yapacak. Çalışır hale geldiğinde http://github.com/alierkanimrek/ adresindeki deposundan indirilebilecek. GUI Meraklıları için bir de ekran görüntüsü;


17
Kas
Kendinize özel Pardus kurulum ortamı hazırlayabileceğiniz Paso'nun 0.1 sürümü hazır. http://github.com/alierkanimrek/paso/downloads Adresinden indirebilirsiniz, arşivi açıp src dizininde "python paso.py" komutunu çalıştırmanız yeterli. Nasıl kullanacağınıza dair kısa açıklamalar http://wiki.github.com/alierkanimrek/paso adresinde var. Tabii eksikler çok http://github.com/alierkanimrek/paso/issues adresinden bilinen hatalara bakabilirsiniz.

Xfce önkurulumlu Pardus için bir .paso hazırladım http://groups.google.com.tr/group/antalya_linux/files adresinden indirebilirsiniz.
12
Kas
Paso'nun TODO dosyasında alt sıralarda olan (.pisi dosyalarını örnek aldığım) XML biçimli dosya desteğinin diğer ihtiyaçlar için bir zorunluluk olduğunu fark edince ilk sıraya onu aldım ve şu anda hazır, ama henüz testlerini tam yapamadığımdan commit etmedim. Bu, şu ana kadar hazırlanan paso dosyalarının güncel paso ile okunamayacağı anlamına geliyor, belki bir çevirme betiği yazabilirim, o konuda söz vermeyeyim. Ayrıca Paso dosyasına hazırlayan kişinin isim ve e-posta bilgilerini ekleme ve hazırlanan paso ile ilgili açıklamalar ile yapılan çalışmanın varsa internet adresini ekleme gibi güzellikler de hazır.

Şu anda git deposundaki Paso Testing'i kullananlar hazırladıkları paso dosyalarını yakında commit edeceğim Paso 0.1 ile kullanamayacak! Yani hazırladığınız Paso dosyalarını yayınlamadan önce biraz daha bekleyin ve 0.1 ile tekrar hazırlayıp öyle yayınlayın derim.

http://armuting.blogspot.com/2009/11/paso-ile-guncel-pardus-kurulumu-yapn.html
http://armuting.blogspot.com/2009/10/pasoyu-yaynladm-pardus-seckilerine-yer.html
8
Kas
Pardus seçkileri oluşturmak için yazmaya başladığım Paso'yu sonunda yayınladım, http://github.com/alierkanimrek/paso adresinden indirip hemen kullanılabilir, Qt4 arayüzlü bir Python betiği sonuçta.

Pisi paketi ve çevirisi için henüz erken olduğunu düşünüyorum, temel işlevleri yerine getirse de henüz pek çok eksiği ve eminim bilmediğim pek çok hatası var. Nasıl kullanıldığına dair bir örnek yapıp ekran kaydı aldım, örnekte Gnome'lu Pardus kurulum ortamı hazırladım. (Tam ekran izleyin)





Paso ile istediğiniz paketlerden oluşan size özel bir Pardus kurulum imajı oluşturabilirsiniz. Daha önemlisi bu imajları oluşturmak için kullandığınız .paso dosyasını paylaşarak herkesin kendi sisteminde sizin hazırladığınız imajları oluşturmasını da sağlayabilirsiniz. Ama unutmayın ancak kurulmuş bir Pardus sistemindeki paketlerden oluşan bir kurulum seçkisi hazırlayabilirsiniz.

Paso dosyaları sadece paketlerin hangi depolarda olduğu bilgisini içeren küçük dosyalardır,, paylaşması kolaydır, isterseniz internetteki depolarda olmayan kendi hazırladığınız paketleri de paso dosyası ile paylaşıp oluşturulacak imaja dahil edebilirsiniz. Kurulum bildiğiniz Pardus kurulumu olacak.

Yakaladığınız hataları ve önerileri github'dan iletebilirsiniz, ama yazılım ile hobi olarak ilgilenen bir amatörüm ve bu işlere kısıtlı zaman ayırabiliyorum, geri dönüş için acele etmeyin :) Ayrıca İngilizcem çok iyi olmadığından bu konudaki düzeltme önerilerini de memnuniyetle karşılarım.
17
Eki
İş güç özel yaşam derken eğlenceye kalan zaman azalıyor, benim eğlencem de kodlarım. Bir süredir çalıştığım Paso artık ayaklandı ve iş çıkarmaya başladı ama daha oturup adam akıllı test edemedim. Çünkü test aşamaları uzun zaman gerektiriyor, sanal makinede Pardus kurulumu (hadi bunu sanal disk kopyalarıyla hallediyorum) değişik paketlerin kurulumu veya kaldırılması, paso ile tekrar imajın oluşturulup sonra bu imajın kurulması falan... Bu sabah Xfce'li Pardus kurulumu yaptım ve birkaç hata düzelttim;


Geçenlerde yaptığım ilk testte çok ilginç bir durumla karşılaştım, Paso ile oluşturduğum iso dosyalarıyla yaptığım kurulumlarda /boot/grub/message dosyası oluşturulmuyor. Bu dosya gfxtheme-pardus-boot paketinin kurulumu sırasında oluşturuluyormuş, paket hatasız bir şekilde kuruluyor ve ayarlanıyor görünüyor ama... Neyse şimdilik bunun üzerinde duracak zamanım yok, Gnome'lu Pardus gibi birkaç denemeden sonra kodları yayınlamak için acele ediyorum.
21
Eyl
Üzerinde çalıştığım proje hayal ettiğim gibi gerçekleşirse isteyen herkes kendi seçtiği paketlerden oluşan özel bir Pardus Kurulum ortamı oluşturabilecek. Hatta bunu küçük (-1MB) dosyalarla paylaşabilecek. Yani içinde oyunlar olan kendi kurulum DVD'nizi hazırlayabileceğiniz gibi örneğin bir başkasının hazırladığı Xfce paketlerinden oluşan seçkisini de indirip kurulum ortamı olarak inşa edebileceksiniz.

Projeye "Paso" adını verdim, bayram tatilinden önce birkaç temel Python sınıfı yazmıştım, tatilde fırsat buldukça da Qt ile arayüz hazırladım, epeydir Qt ile ilgilenmiyordum arayüz giydirmek çok zaman alan bir işmiş. Paso iki bölümden oluşuyor, hazırlama ve inşa bölümleri. Hazırlama bölümü çalışır hale geldi, inşa bölümüne ise bugün başladım.



Bir an önce temel işlevlerle kullanıma açmak için acele ediyorum, bu nedenle bazı özellikleri yazmadan bıraktım, örneğin: kayıt dosyasında xml yerine düz metin biçimi kullandım, options menüsünde olmasını istediğim seçenekleri ve hazırlama aşamasındaki exclude işlemini yazmadım, bazı ayarları koda gömdüm, inşa bölümünde de atlayarak ilerliyorum vs. En azından bir alpha seviyesine gelince sourceforge gibi bir yere GPL lisansıyla yükleyeceğim, ama tatil bitiyor, birkaç hafta bekleteceğim sanırım.
17
Haz

(Kaptan Pardus welcome wizard which aims to help user to configure basic settings on first boot.)

Note: This is the Beta release for Kaptan 4. Design (graphics, colors, layouts) can change until Pardus 2009 stable release (30 days to launch! \m/)

Kaptan4 looks like Kaptan3 but it is fully written in Qt4 and Python. As always, comments are appreciated :)


More screenshots ->








13
Şub

Malum Pardus 2009 ile ilgili çalışmalarımız hızla sürüyor, mevcut araçların KDE 4 ve Teknolojileri ile uyumlu bir şekilde çalışması için ilk adımı Servis Yöneticisi için atmıştım, sıra masaüstünde en çok kullandığımız araçlardan biri olan Ağ Yöneticisi’ne geldi; bakalım bizleri neler bekliyor:

nm-applet

Ekran görüntüsüne tıklayarak eğlenceli ve teknoloji kokan bir kaydı izleyebilirsiniz ;) Ayrıca burada da Ağ Yöneticisi Veri Motoru ile ilgili bir kayıt mevcut ;)

(Henüz geliştirilme aşamasında olduğunu unutmayın)

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Reddit

19
Oca

Amerika kıtasındaki KDE geliştiricilerinin daha rahat katılabilmesi için KDE Vakfı Akademy etkinliği ile birlikte ikinci bir etkinlik daha yapmaya karar verdi, her 6 ayda bir; önce Akademy(Avrupa’da) sonrasında ise Camp KDE(Amerika’da) etkinliği gerçekleştirilecek. “KDE 4.0 Sürüm Etkinliği” adı ile ilk kez geçen sene, “Camp KDE” adı ile de ikinci kez bu yıl gerçekleşen etkinliğe Gökçen ile birlikte katıldık (hala buradayız :))..

KDE & Distros

KDE People

KDE People & Gökçen

Bu yılki etkinlik bir hafta sürüyor ve Jamaika‘da gerçekleştiriliyor. Buradaki takvimden de görebileceğiniz gibi ilk iki gün seminerler ardından planlanmamış (BoF) seminerler ve KDE geliştirme günleri yapılacak. Bende Marcus D. Hanwell(Gentoo) ile birlikte Pazar günü (bu arada doğum günümdü Pazar :)) “KDE ve Dağıtımlar” başlıklı bir sunum yaptım (pdf) , Marcus öncelikle Gentoo’da KDE paketlerini nasıl yaptıklarını, ne tip problemlerle karşılaştıklarını ve bunlarla ilgili buldukları çözümleri anlattı. Ardından bende Pardus için geliştirdiğimiz araçları ve 2009 sürümü için neler planladığımızı anlattım. Güzel geçti, 2009′da kullanılmak üzere geliştirdiğim Servis Yöneticisi ve Plasmoid’ini pek bi beğendiler, bizde mutlu olduk tabi :)

Service-manager

Bu arada 2009 ile ilgili aklınızda birşeyler oluşması adına şu videoyu izlemenizi tavsiye edeyim ;)

8
Eyl
Soru: Emekleme aşamasındaki bir "python coder" bu konuyu proje olarak seçerse ne olur?
Cevap : pogy.tar.gz

İlgililerin paketteki README dosyasını okumasını... (Henüz beta bile olmadığını düşünerek pisilemedim.)
23
Ağu
Pardus için yazdığım çevrimdışı güncelleme yardımcısını kurulum CD'sinde bulunmayan PyQt4 ile geliştirmişim. Geliştirmişim diyorum çünkü bu trajik-komik durumu interneti olmayan bir kullanıcının test ederken aldığı "
ImportError: No module named PyQt4" hatasıyla anlamış olmamdan dolayı yaşadığım dumuru hala üzerimden atamadım. :D

Bu sabah programı pek içimden gelmeyerek PyQt'ye uyarlamak için biraz kurcaladım ama bu iki kütüphanenin birbirinden temel farklılıkları olduğunu anlayınca bu işi şimdilik bir kenara bırakıp programı bir komut satırı aracına dönüştürmenin daha az acı vereceğine karar verdim. Bu projeyi Qt ve özellikle QtXml'i tanımak için yapmıştım, beni teselli eden herhalde bu amacıma ulaşmış olmam oldu. Tabii bunu yaparken işe yarar bir şeyler ortaya çıkmasını da istiyordum.

Ancak kodlarla boğuşurken bu defa farklı olarak üyesi olduğum www.live365.com'dan bir Smooth Jazz [1] kanalını Amarok ile açtım. Kod yazarken ihtiyaç olan konsantrasyon, meditasyon, navigasyon vs.için oldukça etkili olduğunu fark ettim. Genelde sıkı bir Jazz dinleyicisi değilim ama sesi fazla açmadan yan taraftaki bir caz kulübünden odaya süzülen melodiler havasında dinlenen bu tür Cazın "Cazz'n Gazz" etkisini de hiç hafife almayın ve deneyin derim.

[1] http://www.live365.com/stations/bo67
15
Tem


Bakalım zaman bulup bitirebilecek miyim? Aslında sistemdeki mevcut paketleri ve depo indekslerini tarayan birkaç python sınıfı yazdım, hatta konsoldan güncellenecek paket listesini bile aldım, yani işin özü tamam gibi ama derlenip toparlanması ve hata ayıklaması var. Hadi hayırlısı...