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.
Şimdi Signal-Slot kavramı ile ilgili basit örnekler yapalım.
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
);
#include <QObject>
class MyClass : public QObject
{
Q_OBJECT
public:
MyClass() { }
private:
int val;
public slots:
void setValue(int _val);
signals:
void valChanged(int nVal);
};
void MyClass::setValue(int _val)
{
val = _val;
emit valueChanged(_val);
}
Dikkat edilmesi gereken nokta signal olarak tanımlanan metodun implementasyonu yapılmamıştır.
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
Comments