Qt C++ ile Signal-Slot kavramı

Qt C++ ile Signal-Slot kavramı

Herkese merhabalar, bu yazımızda sizlerle QT ile C++ dilinde Signal-Slot kavramı hakkında konuşacağız ve kullanımı, faydaları ve tanımlama yöntemlerinden bahsedeceğiz.

Hadi başlayalım ve ilk olarak Sİgnal ve Slot kavramlarının ne olduğundan bahsedelim.

Signal Nedir ?
Sinyaller bir fonksiyonun içerisinde public olarak tanımlı olan metodlardır. Tanımlı olduğu sınıfın içerisinde bir değer değiştiğinde bu metodlar emit yapılır ve, bu signale bağlı olan diğer metodlar otomatik olarak çalıştırılır.
Signaller grafik arayüzden bağımsız olarak çalıştıkları için çalışmaları esnasında arayüzü kilitlemezler ve istendiği takdirde arayüzdeki veri güncellemelerini sorunsuz olarak gerçekleştirirler.

Önemli Not!
Signaller header dosyalarında SIGNALS altından tanımlanırlar ve .cpp dosyalarına metod olarak tanımlamaları yapılmamalıdır.

Şimdi birde SLOT kavramına bakalım.

Slot Nedir?
Slotlar normal C++ metodları olarak tanımlanırlar ve tanımlamalarıda C++ metodları ile aynı mantıkta yapılmalıdır.Slotlar header dosyalarında PUBLIC SLOTS kısmında tanımlanırlar. Normal C++ metodlarından farkları ise signallere bağlanırlar ve signaller emit yapıldıklarında otomatik olarak çağrılırlar.

Peki Signal-Slot kavramı nedir?
Signal-Slot kavramı ile nesnelerin kendi aralarında iletişim kurmalarına olanak tanıyan ve kendi aralarında birbirlerinin metodlarının çağrılabilmelerini sağlayan ve aynı zamanda birbirlerine veri aktarımını daha kolay hale getiren bir programlama tekniğidir.

  • Signal-Slot kavramı Qt'nin temelini oluşturan kavramlardan bir tanesidir ve Meta Object Compiler tarafından dönüştürülür.
  • QObject veya onun yan sınıflarından türetilen bütün sınıflar signal-slot kavramını kullanabilirler. Eğer kullanılmak istenen sınıf böyle bir sınıf değilse ve Signal-Slot kullanılacaksa Q_OBJECT makrosu ilgili sınıfın private bölgesine eklenmiş olmalıdır.
  • Kullanıcı arayüzündeki değerlerin anlık olarak başka sınıflar tarafından değiştirilmeleri gerektiğinde Signal-Slot kavramı çok büyük esneklik sağlamaktadır.
  • Sıralı olarak yapılmak istenen işlerde Signal-Slot kavramı çok kullanışlıdır.
  • Qt içerisinde built-in olarak gelen ve tanımlanmış sınıflara ait olan Signaller ve Slotlar mevcuttur. Ek olarak bizlerde kendi işlemlerimize göre Signaller ve slotlar tanımlayabiliriz.
  • Signaller sadece void olarak tanımlanabilirler ve herhangi bir değer döndürmezler.
  • Slotlar normal C++ metodları olarakta kullanılabildiğinden değer döndüren metodlar olarak tanımlanabilirler. Signaller gibi illaki void olmak durumunda değillerdir.
Aşağıdaki görselde Signal-Slot kavramını basitce gösterilmiştir: Qt C++ Signal Slot Example Diagram

Şimdi Signal-Slot kavramı ile ilgili basit örnekler yapalım.

İlk olarak Signal slot bağlantısını yapabilmek için gereken QObject sınıfı içerisinde gelen connect metodlarına bakalım. Aşağıda iki yöntemin söz dizimleri verilmiştir.

Eskiden beridir kullanılan String-Based connection


connect(
    sender, SIGNAL( valueChanged( QString) ),
    receiver, SLOT( updateValue( QString ) )
);

Ve non-String yöntemdir.


connect(
    sender, &Sender::valueChanged,
    receiver, &Receiver::updateValue
);
Aşağıda örnek bir C++ sınıf tanımlaması ve içerisinde signaller ve slotların tanımlamaları bulunmaktadır.

#include <QObject>

class MyClass : public QObject
{
    Q_OBJECT

public:
    MyClass() { }

private:
    int val;

public slots:
    void setValue(int _val);

signals:
    void valChanged(int nVal);
};
Aşağıda bu sınıfın implementasyonu verilmiştir.

void MyClass::setValue(int _val)
{
        val = _val;
        emit valueChanged(_val);
}

Dikkat edilmesi gereken nokta signal olarak tanımlanan metodun implementasyonu yapılmamıştır.

Şimdi bu sınıfta tanımlanan signali ve slotu birbirine bağlayalım. Bu işlemi her iki connect metodu içinde deneyelim.

String-based yöntem:


MyClass m1, m2;
connect(
    m1, SIGNAL( valChanged( int ) ),
    m2, SLOT( setValue( int) )
);

Non-String-base connect metodu:


MyClass m1, m2;
connect(&m1, &MyClass::valueChanged,
                &m2, &MyClass ::setValue);

connect metodları içerisinde aynı sınıfa ait olan signal ve slotları bağlamış olduk. Bu işlem aynı sınıf içerisinde yapılabildiği gibi farklı sınıflar içinde aynı şekilde yapılabilmektedir. Qt içerisinde gelen widgetların sahip olduğu kendi signalleri ile bize ait olan başka bir arayü nesnesi değiştirilebilmektedir.

Örnek olarak Qt ile bir QTimer nesnesi üzerinde bir örnek yapalım. QTimer sınıfında bulunan timeout() signali belirlenen her intervalde emit otmatik olaak emit yapılır. Bu sayede uygulamamızda bunu kullanarak bir zaman sayacı uygulaması yapabiliriz.


QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &MainWindow::updateTime);
timer->start();

Buradaki QTimer her timeout olduğunda (yani her saniye), belirtilen fonksiyon çalışacaktır. Bu sayede geçerli saat bilgisi her saniye güncellenmiş olacaktır.

Bu yazımızda buraya kadar.

Burak Hamdi TUFAN


Tags


Share this Post

Send with Whatsapp

Post a Comment

Success! Your comment sent to post. It will be showed after confirmation.
Error! There was an error sending your comment. Check your inputs!

Comments

  • There is no comment. Be the owner of first comment...