You are on page 1of 7

Qt Pencereleri

Kaya Ouz
<kaya@kuzeykutbu.org> Bu belge ve ierisindeki kodlar GPL lisansldr.

Pencere var, pencere var


Daha nce okumadysanz, belgeler sayfasndan tekrar bir Qt'ye Giri belgesine bakn. Orada pencerelere bir giri yapmtk. Ben burada yine bir zet geeceim. Grafik kullanc arayz programlamada TOP_LEVEL_WINDOW ya da MainWindow olarak geen esas pencereler vardr. Bu pencereler, bu belgeyi okuduunuz internet taraycs gibi programlarn "ana" pencereleridir. Bu pencere iinde btn ilemler olur ve genelde bu pencereyi kapattnzda program da kapanverir. Dier pencerelere Dialog Window deniyor, ayn ekilde Diyalog pencereleri olarak evirebiliriz. Diyalog penceresi, adndan da anlalaca gibi bizimle ksa bir etkileime girip kapanan pencerelerdir. Bunlara rnek menden Dosya ve arkasndan A dediimiz zaman kan "Dosya Ama" penceresi. Burada iinizi grdkten sonra program kald yerden devam eder. Bu diyalog pencereleri de kendi aralarnda ikiye ayrlrlar. Bunlardan ilki, Modal denen ve pencere iini bitirene kadar alttaki pencerelere eriime izin vermeyen pencerelerdir. "Dosya A" pencereleri genelde bu ekildedir. Dierleri ise akken dier pencerelere bir kstlama getirilmez. Bunlara da Modeless ya da Non-Modal pencereler denir. rnein bir metin dzenleyicideki "Ara" penceresi gibi. Bu Ara penceresi bir kelimeyi ya da ifadeyi ararken alttaki ana pencerede dzenlemeye izin verir... imdi pencerelerle nasl ba edeceimizi renelim.

Designer Dosyalar
Pencere tasarm vs. ilemler iin elle kod yazmanza gerek yok. Designer denen arala istediiniz arayz hazrlayp kaydedin. Uzants "ui" olan bu dosyalar basit birer XML dosyalardr. Qt'nin bizden habersiz alan uic (ui compiler, daha dorusu user interface compiler) komutu bu XML dosyasn bir balk, yani header dosyasna dntrr. Bunu elle yapabilirsiniz, yani komutu verip bir header dosyas alabilirsiniz. Ama bunun yerine qmake kullanarak proje ynetimi ile beraber gitmeniz tavsiye edilir. Bylece bu dosyalarnz qmake tarafndan otomatik olarak alglanp uic'den geirileceklerdir.

Designer ile tr pencere yaratabilirsiniz: Ana Pencereler (MainWindow), Diyalog pencereleri (Dialog) ve paracklar (Widget)... Ana pencere ve diyalog pencerelerini az ok biliyorsunuz ama paracklar ne iimize yarayacak? Paracklar dinamik sekme yaratmada kullanacaz. lerleyen konularda deineceiz :) Orta ve kk lekli programlarnz genelde bir ana pencere ve onun etrafnda alan diyalog pencerelerinden oluur. Bu yzden ncelikle ana pencerenizi tasarlamanz ve yeni bir dizin altnda kaydetmeniz, arkasndan da ihtiyacnz olduka diyalog pencerelerini yaratmanz izlenecek en olaan yollardan biridir. Var olan pencerelerle alrken qmake -project, qmake, make lsnn sadece son admn altrmanz yetecekken, yeni bir pencere eklediinizde sorun kabilir. Bunun iin qmake lsnden nce "make clean" diyerek ortam temizleyin. Arkasndan da Makefile ve ".pro" dosyanz silin. qmake lsn tekrar edin ve tekrar sorunsuz derlenecektir.

Mama Kin
Mama Kin, Aerosmith'in gzel bir parasdr, Guns 'n Roses da "Lies" albmnde syler bu paray. Szlerinde "Keep in touch with mama kin" derler, yani annenizin akrabalar ile iletiimi koparmayn gibisinden. Ne alakas var derseniz, pencere yaratmak iin torunlara ihtiyacnz vardr. Designer ile oluturduunuz ui dosyalar uic'den getikten sonra bir header dosyas oluyor demitik. Bu header dosyalarnn iinde QMainWindow'dan tretilmi bir snf vardr. Bu snf Ui denen bir namespace altndadr. imdi yukarda geen tretilme, header, namespace gibi kelimeler size yabanc geliyorsa yle syleyelim, o dosyann iinde QMainWindow'un bir ocuu var. ocuk annesine pek benzemiyor, ondan daha renkli. ocuun da kendi bir ocuu olunca daha da gzel olacak. te bu son ocuk bizimdir :) Biz uic'den getikten sonra oluan header dosyasndaki snftan ve QMainWindow'un kendinden treteceiz penceremizi...
#include <QMainWindow> #include "ui_pencere.h" class AnaPencere:public QMainWindow, Ui::MainWindow { Q_OBJECT public: AnaPencere():QMainWindow() { setupUi(this); } };

Burada pencere.ui dosyasndan oluacak olan ui_pencere.h dosyasn include ediyoruz nce. Kendi snfmzn ad AnaPencere ve bu snf QMainWindow ile ui_pencere.h dosyasndaki Ui namespace'i altndaki MainWindow'dan tretiyoruz... Buraya kadar sorun yok. Ondan sonra kurucu (constructor) iinde, yine ui_pencere.h dosyasnda Ui::MainWindow'un bir metodu olan setupUi'yi aryoruz, bu Designer'da oluturduumuz tasarmn yaplmasn salyor. Tabii bu arada kurucuyu arrken, QMainWindow'un kurucusunu da altryoruz (

AnaPencere():QMainWindow() ). te penceremiz hazr! Ayn Designer'da yarattmz ekilde... Buna biraz ilevsellik kazandrmak istiyorsak biraz sinyal / slot ilikileri kurmamz yeterli olacaktr.

Dialog Pencereleri
Tek pencere ile snrl kalmak elbette skc. Bu yzden bu ana pencereye biraz sinyal slot ile yeni ilevler kazandrp yeni bir pencere atralm. Hatta, pencereden deerler alp kullanalm! stte ana pencereyi hi gstermedik, ben size bir ekran grnts sunaym: Figure 1. Pencere Demo

Burada grdnz zere bir "Yeni Pencere" QAction'mz var. Menye yazdnz her satr bir QAction oluyor :) Bunun dnda beyaz alan bir QListWidget. Yani bir liste... imdi "Yeni Pencere"ye tklayacaz, arkasndan bir pencere alacak. Oraya bir bilgi gireceiz, girdiimiz bilgi de listeye eklenecek :) Kolay deil mi? Basit bile olsa aslnda birok ilem bu ekilde yaplyor. QAction'lar doldurmadan nce, diyalog penceremizi tasarlayalm: Figure 2. Diyalog Demo

Buraya kadar her ey normal. Ama bu iki pencere hala Designer'da akken, size bu pencerelerin isimlerini gstermek istiyorum: Figure 3. Designer'da Ana Pencere zellikleri

Bakn, burada objectName olarak MainWindow duruyor. Bu, Ui::MainWindow ifadesindeki MainWindow. imdi diyalog penceremize bakalm: Figure 4. Designer'da Diyalog Penceresi zellikleri

Burada grdnz gibi, bunun ad Dialog. Yani Ui::Dialog olacak. Ama birden fazla pencere kullanacaksanz bu isimler akacaktr. Bu yzden, eer ok form olacaksa bunlara yeni isimler vermeniz iyi olur. Burada baka penceremiz olmayacak, o yzden ntanml bu deerler iimizi grecektir. Ama deitirmek isterseniz, Designer'da pencerenin bo bir yerine sa tklayp "Change Object Name" diyerek yeni ismi girebilirsiniz. Pekala, imdi diyalog penceremizi kaydettik, diyalog.ui, imdi bir temizlik yapalm (make clean) ve diyalog.h dosyamz yazalm:
#include <QDialog> #include "ui_diyalog.h" class dialog:public QDialog, Ui::Dialog { Q_OBJECT public: dialog(QWidget *parent):QDialog(parent) { setupUi(this);

} };

Burada her ey sanki MainWindowdaki gibi. QMainWindow yerine QDialog'u ekledik, dikkat edin, bu sefer QDialog ve Ui::Dialog'tan trettik. Burada Ui::Dialog ifadesindeki Dialog, stte ekran grntsndeki Dialog. Eer onu formPencere yapsaydk, Ui::formPencere diyecektik ;) Bunun dnda dikkat etmeniz gereken bir dier nokta QWidget *parent ifadesi. Diyalog pencerelerinin bir parent nesnesi olmal. QMainWindow ve QDialog, QWidget'tan tredikleri iin biz oraya bizim AnaPencere'yi koyacaz. QDialog'un kurucusu (constructor) da bu QWidget' alr :) Hemen hemen iki pencereyi de yarattk, ama bu pencereler nasl alacak. Elbette bu i iin ana pencereye biraz ilem yapmamz gerekecek. "Yeni Pencere" QAction'n bir slot'a balayalm ve pencereyi atralm. Yeni anaPencere.h'mz u ekilde:
#include <QMainWindow> #include "ui_pencere.h" #include "diyalog.h" class AnaPencere:public QMainWindow, Ui::MainWindow { Q_OBJECT public: AnaPencere():QMainWindow() { setupUi(this); connect(actionYeniPencere, SIGNAL(activated()), this, SLOT(slotPencere())); } public slots: void slotPencere() { diyalog *yeni = new diyalog(this); yeni->exec(); } };

Pekiii! imdi burada ne oldu? ncelikle diyalog.h dosyasn include etmeyi unutmadk (tamam ilk bata unuttum gene, ama fark ettim hemen :) ) Ondan sonra "actionYeniPencere"mizi, slotPencere denen hemen aaya yazdm metoda baladk. O metod napyor peki? Basite diyalog denen snfmzdan (kendisi diyalog.h iindeydi) bir yeni pointer yaratyor, ad yeni :) Bakn yaratrken new dialog(this) ifadesini kullandk. Yani this dediimiz, bir QMainWindow gnderdik iine. O zaman ne oldu? Diyalog penceremiz ana penceremizin tam ortasnda kt. Burada this yerine 0 ya da null derseniz ekrann ortasnda kar. Ama pencereye ait diyalog pencerelerinin pencerenin ortasnda kmas daha iyidir :) Peki bu pencere hibir ilem yapmyor. Belirdikten sonra Kaydet / iptal neye basarsanz basn kapanyor. Amacmz neydi? O QLineEdit'e bir eyler yazdrp, QListWidget'a eklemek! O zaman size biraz QDialog'un yapabileceklerinden bahsedeyim. Bu iki dme

Designer ile hazrlandnda iki tane Slot'a ballar aslnda. Biri, Kaydet daha dorusu, accept() denen slota bal, dieri de, ptal yani, reject() denen slot'a bal. Bu iki slot QDialog'un slotlar. Eer kullanc Kaydet'e basarsa accept() slotu anaPencere.h iindeki slotPencere() fonksiyonuna QDialog::Accepted deerini dndryor. Orada yeni->exec() herhangi bir deere eitlenmemi, ama eitlersek durumu, yani kullancnn accept / reject ettiini renebiliriz. Btn dosya yerine deien yer inceleyelim: olan void slotPencere() metodunu tekrar

void slotPencere() { diyalog *yeni = new diyalog(this); if (yeni->exec() == QDialog::Accepted) { // demek ki kabul etmi! } }

Harika! accept() ifadesini artk kullanabiliyoruz, ama deeri nasl alacaz? Eer yeni->lineEdit->text() gibi bir dnceniz varsa byle deil. nk QDialog'un accept() ifadesinden sonra ona ulaamyoruz. Bunun yerine diyalog.h dosyasndaki snfmza bir deiken daha ekliyoruz, ad QString yazilan:
#include <QDialog> #include "ui_diyalog.h" class diyalog:public QDialog, Ui::Dialog { Q_OBJECT public: QString yazilan; diyalog(QWidget *parent):QDialog(parent) { setupUi(this); connect(okButton, SIGNAL(clicked()), this, SLOT(slotKaydet())); } public slots: void slotKaydet() { yazilan = lineEdit->text(); } };

Neler oldu imdi? okButton'u zaten bir slot'a balyd hani? Evet, hala accept() slotuna bal. Ama biz onu bir de bu slot'a, slotKaydet()'e baladk. Bu slot ile yazilan deikenine lineEdit iindeki metni aldk! Artk bunu void slotPencere() iinde kullanabiliriz:
void slotPencere() { diyalog *yeni = new diyalog(this); if (yeni->exec() == QDialog::Accepted) { new QListWidgetItem(yeni->yazilan, listWidget); } }

Vay! Ne kadar basitmi! :) QListWidget'a yeni bir satr eklemek iin bir

QListWidgetItem kullanyoruz. Detayl bilgi iin Assistant'a bakabilirsiniz. Burada new ile aslnda yeni bir pointer dnyor ama ona ihtiyacmz yok, o yzden braktk. yeni->lineEdit'e ulaamasak bile artk yeni->yazilan'a ulaabiliyoruz ve ite listeye yazdmz ifade eklendi. Burada elbette kontrolleri de yapmak lazm, mesela bo brakmsa "ltfen bir metin giriniz" vs. yazmak lazm deil mi? Onlar da yapalm. O zaman ilk iimiz okButton'dan accept() slot'unu kaldrmak olmal. Bu i iin Designer' kullanabilirsiniz. Hemen oradaki SIGNAL SLOT EDITOR altnda okButton, clicked, Dialog, accept satrn seip kaldrn. Kaydedin. Artk accept olayn kendimiz yazacaz. Tek yapmamz gereken daha nce yazdmz slotKaydet() metodunun sonunda bir kontrol edip accept() ifadesini yazmak. slotKaydet() metodunu tekrar yazalm:
void slotKaydet() { if (lineEdit->text() == "" || lineEdit->text() == QString::null) { QMessageBox::critical(this, "Hata!", QString::fromUtf8("Ltfen bo brakmaynz!")); return; } yazilan = lineEdit->text(); accept(); }

Burada, en baa, #include <QDialog> ifadesinden sonra #include <QMessageBox> eklemeyi unutmayn! Burada artk accept() slotumuz slotKaydet olduu iin gvenle kontrol ediyoruz lineEdit->text() ifadesini. Eer bosa veya null ise bir hata mesaj verip dnyoruz. Deilse, yazilan deikenine yazp, accept() ile ilemi bitiyoruz :) Artk btn ilevleri yerine getiren basit ve etkili bir pencere / diyalog ikilimiz var, hayrl uurlu olsun! Sekmelerle ilgili yazy artk bir sonrakine anlatrm :) Btn kaynak kodlar belgeler sayfasndan indirebilirsiniz.

You might also like