25 Nisan 2010 Pazar

Arayüz Programlama::Bölüm 3:"SIGNAL ve SLOT"

SIGNAL ve SLOT iki nesneni bir birleri ile iletişim kurmasına yararlar. SIGNAL ve SLOT mekanizması Qt'un en önemli özelliklerinden biridir.Arayüz (GUI) programlamada, bir widgetta bir değişiklik olduğunda diğer widget tarafından fark etdilmesini isteriz yaninesneleri bir birleri ile iletişim kurmasını isteriz. Örneğin kullanıcı kapat düğmesine bastığında pencerenin kapanması gibi.

Eski toolkitlerde bu durum callback (geri çağrı) kullanarak çözülmüştür.Callback bir fonksiyonu işaret eder. Çalışan bir fonksiyona bir durumu bildirmek istiyorsak kullanacağımız fonksiyonu çalışan fonksiyona işaret ederiz.Çalışan fonksiyonda uygun olduğu zaman işaret ettiğimiz fonksiyonu çalıştırmaya başlar.Ancak bu yöntemin çalışan fonksiyonun, işaret ettiğimiz fonksiyonu doğru argümanlarla çalıştıracağını bilemememiz gibi sorunları vardır yani bu yöntem type-safe değildir.

Qt'da callback tekniğine alternatif olarak SIGNAL ve SLOT'lar kullanılmaktadır. SIGNAL bir durum oluştuğundan yayılmaya başlar.SLOT da SIGNAL çağrılarına cevap veren fonksiyonlardır. SIGNAL-SLOT meknizması type-safe'dir.SIGNAL'ın imzası SLOT'un imzası ile eşleşmelidir.Bu konuda derleyici eşleşmeyen imzaları tespit ederek bize yardım etmektedir.Qt widgetlarında bir çok tanımlanmış SIGNAL ve SLOT mevcuttur.Gerektiğinde programcıda kendi SIGNAL ve SLOT'unu yazabilektedir.SIGNAL ve SLOT'lar bir birleri ile QObject sınıfının connect methodu kullanılarak ilişkilendirilir.

Şimdi SIGNAL ve SLOT'u basit bir örnekle daha iyi anlmaya çalışalım. Yapıcağımız örnekte 2 tane widget ve bu widgetların hazır SIGNAL ve SLOT'larını kullanacağız. Yazacağımız program şöyle olacak 1 tane QLabel ve 1 tanede QPushButton nesnesi oluşturacağız. Program şu işi yapacak; QPushButton nesnesine tıklandığında bu nesne sinyal yaymaya başlıyacak ve QLabel nesnesi bu sinyali alıp kendinin kapatma slotunu çalıştıracak ve QLabel nesnesi kapanacak.







#include <QtGui>

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

QPushButton nesne1("QPushButton");
QLabel nesne2("QLabel");

QObject::connect(&nesne1,SIGNAL(clicked()),&nesne2,SLOT(close()));

nesne1.show();
nesne2.show();

return a.exec();
}




6 yorum:

  1. Burak bey, öncelikle yapmış olduğunuz çalışmaları bizlerle paylaştığınız için size teşekkür ediyorum. Sayfanızı büyük bir ilgi ile takip ediyorum, yeni arayüz programlamalarınızı büyük bir merakla bekliyorum. Son olarak seri portu da kontrol edebilirmiyiz çok merak ediyorum. Bununla ilgili örnek yaparsanız çok sevinirim, ilk halısahanızda benden olur. Sağlıcakla kalın

    YanıtlaSil
  2. Eren bey, blogumu takip ettiğiniz için teşekkür ederim. Ümit ederim ki faydalı oluyordur. Seri port işine gelince; ben de seri - usb gibi iletişim türlerine el atmayı istiyorum. Ancak sizinde bildiğiniz gibi bunlar için elektronik donanım gerekiyor. Eğer bu sene kafamdaki bitirme projesini yaparsam bu tür işlere girecek gibi duruyorum. Eğer girersem de yaptığım çalışmaları seve seve paylaşmaya hazırım.

    Kolay gelsin.

    YanıtlaSil
  3. Ellerinize sağlık.Yalnız esas zorluk çekilen nokta
    signal-slot mekanizmasında kendi fonksiyonlarımızı çağırma noktasındadır.Sözgelimi:[code]
    #include
    #include
    #include
    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);

    QPushButton nesne1("QPushButton");
    QLabel nesne2("QLabel");

    QObject::connect(&nesne1,SIGNAL(clicked()),&nesne2,SLOT(close()));

    nesne1.show();
    nesne2.show();

    return a.exec();
    }
    [/code]
    Yazıldığında mekanizma işliyor.Fakat şöyle bir:
    [code]
    #include
    #include
    #include
    #include
    class Cikis:public Q_OBJECT{
    Q_OBJECT
    public:
    Cikis(){a=1;}
    void cikis(){return (exit(a));}
    public slots:
    void cik();
    signals:
    clicked();
    private:
    int a;};

    void Cikis::cikis(){
    emit clicked();
    }

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

    QPushButton nesne1("QPushButton");
    QLabel nesne2("QLabel");
    Cikis b;
    QObject::connect(&nesne1,SIGNAL(clicked()),&nesne2,SLOT(b.cik()));

    nesne1.show();
    nesne2.show();

    return a.exec();
    }
    [/code]

    Böyle ya da başka bir dönüşümle kendi fonksiyonlarımızı icra ettirmekte zorluk çekebiliyoruz.Bunlara da bir açıklık getirirseniz sevinirim.

    YanıtlaSil
  4. Galiba adsızlara cevap verilmiyor he:)

    YanıtlaSil
  5. Yakın zamanda sorunuza cevap vereceğim. Aklımda merak etmeyin.

    YanıtlaSil
  6. Yeminle söylüyorum.Winapi yi çözdüm bunu çözemedim arkadaş.Ne mekanizmaymış ya.Hayır ben kendime burada int toplama(int a,int b){return (a+b);}
    Gibi basit bir fonksiyonu yazamayacaksam ne anladım ben bu işten.Yurtdışındakilere sordum ordan da bir cevap yok.Anlamadım bu işten bi şey yanlış anlama kardeşim sözüm sana değil genel QT yapısı hakkında bir eleştiri benimkisi yanlızca

    YanıtlaSil