24 Aralık 2010 Cuma

User-Manager Class Diagram


Toplantıda proje grubu ikiye ayrıldı ilk grup managerlar ile ilgilenecek, ikinci grup paketleme yapacak. Ben hiç bilmediğim bi konu olan paketlemeyi seçtim. Amacım paketlemeyi her yönüyle öğrenmek. User manager için yapacağım şimdilik son şey bir uml class diagramı oluşturmak oldu. Diagramın son hali bu eksik ve hatalar olabilir.

13 Aralık 2010 Pazartesi

TÜBİTAK'a ÇoMaK Soktuk:)

Tarih 10 Aralık 2010 saat 01:00... Çomak ekibi toplantı için yola çıkar. Esenler otogarına varana kadar herşey iyi gidiyordu. Ancak Metro turizmin azizliğine uğradıktan sonra baya bir gecikmeyle Gebze'ye vardık.
Ve TÜBİTAK... Herşey çok güzeldi. Oraya gitmeden de zaten orada çalışmak gibi bir hayalim bir isteğim vardı. Kapsüllü kapıları görünce biraz ürktüm gerçi ama çabuk geçti:) Kapsüllerin estirdiği soğuk hava Gökmen Göksel, Onur Küçük ve Erkan Tekman ile tanıştıktan sonra sıcacık oldu. Toplantıda önce özgür yazılım felsefesinden konuştuk (konuştuk desem de tam öyle değil aslında:)). Bu konuşma gerçekten çok faydalı oldu. Çok fazla şey öğrendim. Daha sonra ise projenin aşamalarından daha doğrusu "nasıl"ından bahsedildi. Ben nasıl kısmından çok TÜBİTAK ta gördüğüm ortamdan bahsetmek istiyorum. Ofis ortamında çalışmak zorunda kalan herkesin zevkle çalışacağı bir yer. Bu sanırım özgür yazılım felsefesinden gelen bir rahatlık (bir refah ortamı:)).
İkinci gün Özgürlük İçin'e röportaj vermek için gittik. Şimdi burada yazması kolay oluyor ancak gitmeden önce ve röportaj sırasında da oldukça heycanlıydım. O kadar ki ÇoMaK projesinin amacını söylerken bile tıkanıp kaldım, tamamen neredeyim, ben kimim sendromu oldu. Haftaya ajans pardus'u dinleyip görücez:) Ayrıca şundan da bahsetmeliyim ki "özgürlük için"deki ortamın da TÜBİTAK'taki ortamdan eksik kalır yanı yoktu (kapsüllü kapıları düşünmezsek tabi:)). Orada da çok şey öğrendim.Özgürlük İçin topluluk yöneticisi Ali Işıngör, ilerde özgür yazılım camiasında neler yapabileceğimiz konusunda bize çok değerli tavsiyelerde bulundu.

Kısacası bu İstanbul gezisinde ÇoMaK projesinin gidişatı haricinde özgür yazılımcıların aç kalmadığını öğrendim:) Ve elle tutulur gözle görülür bir projenin içinde bulunmaktan müthiş heyecan duydum. Bu heyecanı yaşamamızı sağlayan Necdet Hocamıza, yardımlarından dolayı Gökmen Göksel, Onur Küçük ve Erkan Tekman'a ,tavsiyelerinden dolayı Ali Işıngör'e çok teşekkür ediyorum.

10 Kasım 2010 Çarşamba

KSystemTrayIcon

Miras diagramı:



KSystemTrayIcon modülü, QSystemTrayIcon modülünü miras almaktadır.
QSystemTrayIcon sistem tepsisindeki bir uygulama için bir ikon oluşturmamızı sağlar. Modern işletim sistemlerinin hemen hemen hepsinde masaüstünün özel bir yerinde sistem çekmecesi veya bildirim alanı diye adlandırılan bir bölüm bulunur. Bu bölümde sistemde çalışır durumdaki uygulamaların ikonları ve kısa mesajları görüntülenir.
KSystemTrayIcon KDE platformunda kullanılır. Sistem tepsisinde bir ikona sol mouse butonuyla tıklandığında uygulamanın ana penceresi açılır, sağ mouse butonuyla tıklandığında popup menü ile uygulamaların listesi gösterilir.

Public Slotlar
void
KSystemTrayIcon::toggleActive()
: toggle üzerine girdi olup olmadığını dinler.

Sinyaller:

void quitSelected(): Bir işlemi yerine getirdikten sonra ana pencerenin kapatılmasına yarayan sinyaldir.

Public üye fonksiyonları:

KSystemTrayIcon (QWidget *parent=0): Sınıfın yapıcısıdır. Tepsi penceresine tıklandığında parent widget görünür.

KSystemTrayIcon (const QString &icon, QWidget *parent=0): Yukarıdaki yapıcıyla aynı işi yapar ancak ayrıca sistem tepsisinde kullanılabilecek ikonun ismiyle tanımlanmasını sağlar.

KSystemTrayIcon (const QIcon &icon, QWidget *parent=0): Yukarıdaki yapıcıyla aynı işi yapar.

~KSystemTrayIcon (): Sınıfın yokedicisi.

KActionCollection * actionCollection (): Context menu içindeki olaylara kolay erişim için kullanılır.

QWidget * parentWidget () const: Yapıcı tarafından atanan QWidget'i döndürür.

bool parentWidgetTrayClose () const : Bu fonksiyon false değeri döndürdüğünde pencere kapatma işlemi normal olarak gerçekleştirilir. True değeri döndürdüğünde sistem tepsisiyle ilişkili bir işlem gerçekleştirilir.

static QIcon loadIcon (const QString &icon, const KComponentData &componentData=KGlobal::mainComponent()): Verilen componentDatanın ikon yükleyici sınıfı kullanılarak bir icon yüklenir. Bu ikon sadece sistem tepsisinde gösterilir.

7 Kasım 2010 Pazar

KActionMenu


KActionMenu

KActionMenu için miras diyagramı:




KActionMenu başka eylemlerin bir alt menüsünü tutan kendine özgü birçok özelliğe sahip eylemdir.
Herhangi bir QAction alt menü oluşturmak için kullanılabilir.

Popupmenu eklemek, alt menü oluşturur. Araç çubuğu eklemek, alt menü ile buton oluşturur.


Public üye fonksiyonları:
KActionMenu (QObject *parent): Sınıfın yapıcısıdır. Miras alınan KAction sınıfının setShortcutConfigurable(bool configurable) fonksiyonuna false parametresi vererek kullanıcıya kısayolları düzenleyemeyeceğini gösterir.
KActionMenu (const QString &text, QObject *parent): Sınıfın yapıcısıdır. Burada da setShortcutConfigurable(bool configurable) fonksiyonuna false parametresi vererek. Kullanıcıya kısayolları düzenleyemeyeceğini gösterilir. Ayrıca text argumanı setText() fonksiyonuna parametre olarak girilir.
KActionMenu (const KIcon &icon, const QString &text, QObject *parent): Sınıfın yapıcısıdır. KAction sınıfının KAction (const KIcon &icon, const QString &text, QObject *parent) yapıcısını gerçekleştirir. Burada kısayolu oluşturacak icon, ve text parametreleri girilir ( örneğin &Options, icon: & , text: Options, O Option için kısayol oluşturur.
~KActionMenu (): yokedici.
void addAction (QAction *action): QMenu sınıfının addAction() modulünü çağırır. Eylemlerin menü listesine action eylemini ekler.
QAction * addSeparator (): Bir eylemin separator (ayırıcı) olarak atanmasını sağlar

virtual QWidget * createWidget (QWidget *parent): QWidgetAction sınıfından implement edilir. Özel widgetleri destekleyen taşıyıcı widgete bir eylem eklenmek istendiğinde bu fonksiyon çağırılır.
bool delayed () const: KToolBar bağlanıldığında gecikme penceresi oluşursa true döndürür.
void insertAction (QAction *before, QAction *action): Eylem ekler.
QAction * insertSeparator (QAction *before): Menuye ayırıcı eylem ekler.
KMenu * menu (): Bir menu varsa bu eylemin menusünü bir KMenu olarak geri döndürür. Eğer menü yoksa bir tane oluşturur.
KMenu * popupMenu ():Bir menu varsa bu eylemin menusünü bir KMenu olarak geri döndürür. Eğer menü yoksa bir tane oluşturur.
void remove (KAction *): Menüden KAction tipinde bir eylemi kaldırır.
void removeAction (QAction *action): Menüden QAction tipinde bir eylemi kaldırır.
void setDelayed (bool delayed): delayed=true ise, KToolBar bağlanıldığında bu eylem delayed popup menu oluşturacaktır.
void setMenu (KMenu *menu): menüyü ayarlar.

12 Ekim 2010 Salı

ÇOMAK:)

Bitirme projemizin adını önce kdetognome koymuştuk ancak daha sonra alınan kararla masaüstünü sadece gnome değilde diğer masaüstlerini de destekleyecek şekilde olsun diye değiştirdik. buna bağlı olarak projenin adı önce kdetoall oldu ama dahice bir fikirle son olarak projenin adının ÇOMAK olmasına karar verildi. Bu projeye nasıl dahil olduğumu bitirme projesi başlığında anlatmıştım.
Benim projedeki görevimde belli oldu ben yalı'da yaptığım işe devam edeceğim.Ayrıca user-manager üzerine de çalışacağım. Öncelikle YALI işe kaldığım yerden devam ediyorum.
SrcInstall.py Yali'nın paket kurulumu yaptığı ekrandır. Burada PkgInstaller() sınıfının run() metodunun içerisinde deponun nerede olduğu kontrolü yapılıyor. Deponun adresi repoAddr değişkeninde tutuluyor. Bu değişken installData.py'nin içerisinde bulunuyor. Ön tanımlı olarak none atanmış. O yüzden yükleme sırasında direk Cd'deki depodan yüklemeye başlıyor. Eğer repoAddr değişkeninin var olduğunu düşünürsek şöyle bir kod çalıştırılıyor.

yali.pisiiface.addRemoteRepo(ctx.installData.repoName,ctx.installData.repoAddr)

addRemoteRepo() fonksiyonu yali dizininin pisiiface.py dosyasında tanımlanmakta ancak pisiiface.py 'e baktığımda şunu gördüm

def addRemoteRepo(name, uri):
....if not repodb.has_repo(name):
........addRepo(name, uri)
........updateRepo(name)

addRepo() yine pisiiface.py içerisinde tanımlanmakta

def addRepo(name=None, uri=None):
....if name and uri:
........pisi.api.add_repo(name, uri)

Buradan anladığım kadarıyla pisiiface.py pisi içerisinde olan metodların bir arayüzünü oluşturuyor.

pisi dizini içerisinde api.py ye baktığımda add_repo() fonksiyonunun burada gerçekleştirildiğini umuyordum. Ki evet burada gerçekleştiriliyor. Paketler üzerindeki diğer işlemlerde buraya bağlanarak gerçekleştirildiğini öğrendim.

11 Ekim 2010 Pazartesi

Pardus'a, katkıcı başvurusu yapma

Pardus geliştiricilerinin bildiğim kadarıyla yüzde yüzü Türk olmasına rağmen neden kılavuzların İngilizce yazıldığına anlam verebilmiş değilim. Bugün Pardus'a katkıcı başvurusunda bulundum. Bununla ilgili Türkçe kaynak olması amacıyla gerçekleştirdiğim adımları buraya yazıyorum.

1.Bu adımları "How to be a Contributor?" adlı yazıyı okuyarak öğrendim.
2.Bir bugzilla hesabı almak. Tabi benim vardı bu adımı pas geçtim:)
3.Daha sonra yeni bir hata raporla kısmında dağıtım süreçleri konusunu seçtim.
4.Orada da görüldüğü gibi yeni katkıcı başvurusu kısmı var. Oradan karşıma bir form çıktı.
Bileşen kısmında geliştiriciyi işaretliyoruz.
5.Özet kısmında "Geliştirici adaylık Özge Barbaros" yazdım.
6. Ayrıntılar kısmında ise şu soruların yanıtları olmalı:
  • Hangi dağıtımı düzgün bir şekilde kullanıyorsunuz?
  • Ne zamanda ve hangi dağıtımdan beri Pardus kullanıyorsunuz?
  • Özgür yazılım projesine katkıda bulunmak sizin için ne ifade ediyor?
  • Daha önce bir özgür yazılım projesinde bulundunuz mu? Evetse , hangi proje, nasıl ,ne kadar süre bu projede yer aldınız?
  • Neden Pardus'a katkıda bulunmak istiyorsunuz?
  • Pardus için ne kadar zaman harcadınız?
  • Öz geçmişinizi ekleyin ya da link verin
  • Başvuru geliştiricilik içinse , aşağıda belirtilen daha önce yapmış olduğunuz şeyleri ekleyiniz:
Pardus deposu için hazırladığınız paketleri veya Pardusta yaptığınız düzenlemeler.
bugs.pardus.org.tr de düzelttiğiniz hatalar.
Diğer dağıtımlar için yaptığınız katkılar.
Ve hatayı raporluyoruz. Bir de CV ekliyoruz tabi ki:)

2 Ekim 2010 Cumartesi

user-manager

Bitirme projesinde kodları okumaya başladık. Pazartesiye kadar user-manager kodlarına bakıp anladıklarımı "svn://svn.comu.edu.tr/gpardus" adresine göndermem gerekiyor.
Dün kullanıcı adı ve parolalarımızı aldık.

Daemon: Unix ve diğer multitasking işletim sistemlerinde, daemon, kullanıcının bire bir kontrolünde değilde arka planda yürütülen programlardır. Daemonlar tipik olarak "d" ile biten isimlere sahip olurlar.
Unix'te bir daemonun ebeveyn süreci sıklıkla "init" sürecidir. Süreçler bir çocuk süreç oluşturduğunda (forking: kendisinin bir kopyasını oluşturmak) daemon olurlar.
Sistem daemonları boot zamanında oluşturmaya başlar.Bunlar genelde network isteklerine, donanım aktivitelerine cevap veren veya başka görevleri yerine getiren programlardır.

D-bus: D-bus yazılım uygulamalarının birbirleriyle haberleşmesi için basit bir thread haberleşme (bir veya daha fazla süreç arasında) sistemidir.
D-bus işlevselliği daemon gibi çalışır; genellikle dbus-daemon. Kullanıcılar bunun birçok örneğini oluşturabilir. Bu örneklere kanal adı verilir. Birçok sistem,her kullanıcı için özel bir örnekle ayrıcalıklı bir sistem kanalı gerçekleştirir. Bu özel örneklere gerek duyulmasının sebebi
sistem kanallarının erişim kısıtlamalarına sahip olmasıdır.
Sistem kanalı HAL (donanım-soyutlama katmanı) daemonından sinyal alan süreçlere yoğunlaşır. Özel örneklerin görevi kullanıcı uygulamaları arasındaki sınırsız iletişimi önlemektir.

Python'un D-bus modülü:
dbus modülünü kullanabilmek için öncelikle bus nesnesi oluşturmak gerekir. Bu nesne iki amaçla oluşturulabilir:

1.si Session bus:her kullanıcı için farklı oturum bu oturum masaüstü uygulamalarının haberleşmesinde kullanılır.
import dbus

session_bus=dbus.SessionBus()

2.si System bus: genellikle boot anında başaltılır. Sistem servislerinin haberleşmesi için kullanılır.Örneğin udev, networkmanager, HAL

import dbus

session_bus=dbus.SessionBus()

Bu ikisi aynı uygulama içerisinde kullanılabilir.

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

31 Ağustos 2010 Salı

Python soket programlama

Python'la soket programlama:

1.socket modülü
socket() fonksiyonu: soketin oluşturulması için kullanılır.

İstemci Program

host= "localhost"
port= 21567
buf = 1024
addr = (host,port)

  • host: Bir host ismi veya IP adresi olabilir. Ben yerel olarak programları denemek istediğim için host="localhost" yazdım. Sunucu internet üzerindeyse IP adresi ve ya domain name kullanılır.
  • port: Bir numara veya sembolik servis ismi olabilir.
  • buf: Soketten transfer edilecek verinin maximum büyüklüğünü ayarlamak için kullanılan değişkendir.
  • addr: İki elemanlı bir demettir ( tuple ). Bu değişken sunucuya mesaj gönderirken kullanılır.
Soketin oluşturulması:

TCPSock=socket(AF_INET, SOCK_STREAM)

Bu kod haberleşmenin TCP protokolüyle yapılacağını gösterir. Bununla yapmamın sebebi FTP 'nin TCP üzerinde çalışması.

Bu parametrelerin anlamı:

  • AF_INET: TCP ve UDP için IPv4 protokolleri
  • AF_INET6: TCP ve UDP için IPv6 protokolleri
  • AF_UNIX: UNIX domain protokolleri
Soket tipi,soket akışında kullanılan iletişim tipidir.Bunlar beş çeşit:
  • SOCK_STREAM: İletişim tabanlı TCP byte akışı
  • SOCK_DGRAM: Datagramların UDP ile transferi, sunucu- istemci doğrulamasına gerek duymayan kendi kendine yeten IP paketleri için...
  • SOCK_RAW: Henüz olgunlaşmamış soketler
  • SOCK_RDM: Güvenilir datagramlar için
  • SOCK_SEQPACKET: Bağlantı üzerinden kayıtlar için bir dizi transfer.
sendto() fonksiyonunu kullanarak sunucuya mesaj göndermek için kod

msg="Sunucuya gönderilecek mesaj"

TCPSock.sendto(data,addr)
--------------------------------------
#!/usr/bin python
# -*- coding:utf-8 -*-



from socket import *

# Soket parametreleri oluşturulur
host = "localhost"
port = 21567
buf = 1024
addr = (host,port)

# Soketin oluşturulması
TCPSock = socket(AF_INET,SOCK_STREAM)

def_msg = "===Sunucuya gönderilecek mesajı giriniz===";
print "\n",def_msg

# Mesajın gönderilmesi
while (1):
data = raw_input('>> ')
if not data:
break
else:
if(TCPSock.sendto(data,addr)):
print "Sending message '",data,"'....."

# Soketin Kapatılması
TCPSock.close()
----------------------------------------------------------------------------------------
Sunucu Programı
Sunucu programda socketi aynı şekilde kuruyoruz. İlk başta değişkenleri oluşturuyorulur:

host= "localhost"
port= 21567
buf = 1024
addr = (host,port)

Soket oluşturulur:

TCPSock = socket(AF_INET,SOCK_STREAM)
Adresi bağlamak için gerekli kod:

TCPSock.bind(addr)

data,addr=TCPSock.recvfrom(buf)
print data
--------------------------------------------------------
#!/usr/bin python
# -*- coding: utf-8 -*-

# Server program

from socket import *

# Set the socket parameters
host = "localhost"
port = 21567
buf = 1024
addr = (host,port)

# Create socket and bind to address
TCPSock = socket(AF_INET,SOCK_DGRAM)
TCPSock.bind(addr)

# Receive messages
while 1:
data,addr = TCPSock.recvfrom(buf)
if not data:
print "Client has exited!"
break
else:
print "\nReceived message '", data,"'"

# Close socket
TCPSock.close()

-------------------------------------------------------------------------------------------
Ben projemde öncelikle ftp protokolünü kullanacağım. Bunun için pythonda ftplib modülü bulunmaktadır.

Python'da FTP istemcisi oluşturmak

İlk adım ftplib modülünü import etmektir.

import ftplib

"socket" modülü arayüze ihtiyac duyan tüm python modülleri tarafından kullanılır. FTP kütüphanesi bunlardan farklı değildir. FTP kütüphanesi öncelikle SOCKS modülüne dayanır, ama eğer model bulunmazsa socket modülüne başvurulur.

Bağlantının başlatılması

Python'a hangi siteye bağlanması gerektiğini söylüyoruz:

ftp = ftplib.FTP('ftp://baglantikurulacaksite.com')

Burada ftplib kütüphanesinin FTP sınıfından bir nesne oluşturuyoruz. Bu sınıftan bir nesne oluşturabilmek için gerekli minimum argüman sunucunun URL'sidir. Bu URL başlangıç değeridir ve geriye bir soket nesnesi döndürür. Bunu ftp değişkenine atadık. Eğer istersek log in bilgilerini de buradan girebiliriz. Bunun söz dizimi şöyle;

handle=ftplib.FTP(host,username,passwd,account_name)

Soket bağlantısı oluşturuldu ama henüz sunucuda oturum açamadık. FTP sınıfı sunucuda oturum açmak için şöyle bir metoda sahip;

ftp.login("mylogin","mypassword")

Daha sonra ne yapılacağı ftp bağlantısını neden açtığımıza bağlı. ftplib modülü binary ve text formatında saklama ve bulup getirmek için metod sağlar.

Text formatı için metodlar:

  • x.storlines(command,file): satır modunda bir dosyayı saklamak için kullanılır.
  • x.retrlines(command,callback): satır modunda bir dosyayı getirmek için kullanılır.
Her method için minimum 2 argüman verilmesi lazım. Her ikiside çalıştırılacak olan komutun açıkça deklare edilmesine gereksinim duyar.

Saklamak için en yaygın komut 'STOR', bulup getirmek içinse 'RETR' dir. Bunlardan başka kullanılan komutlarda vardır.


Söz konusu olan her iki komutun ikinci bölümü dosya ismidir.


'STOR filename' 'RETR filename'

Her metodun ikinci argümanı ne yaptığımızla alakalıdır. Saklamak için dosya nesnesi getirmek için bir callback içerir. Bu callback dosya getirildiğinde ne yapılacağını söylemek için bir fonksiyondur.

Binary mode'ta FTP saklama (store) ve getirme (retrieve)

Binary mode'taki metodların söz dizimi de bir önceki ile aynı ;

  • x.storlines(command,file[,blocksize]): satır modunda bir dosyayı saklamak için kullanılır.
  • x.retrlines(command,callback[,blocksize[,rest): satır modunda bir dosyayı getirmek için kullanılır.
Binary ve text arasında 2 önemli fark vardır.

Birincisi her iki binary komutu seçimli blocksize argümanı için olanak sağlıyor. Bu yüzden binary mode daha hızlıdır.

İkincisi binary retrieve fonksiyonlu seçimli rest argumanına sahiptir. Bu argüman bir dosyanın ortasından indirmeye başlamaya yarar. Bu fonksiyon bütün FTP serverlar tarafından desteklenmez. Eğer sunucu desteklemiyorsa bir error_reply uyarısı alınır.