26 Eylül 2010 Pazar

Qt

"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();
}

Hiç yorum yok:

Yorum Gönder