QT GUI C++ - Signal Slot Kavramı - Part 1
Signal ve Slot nesnesi QT içinde nesneler arası iletişim kurmada kullanılır. Signal ve Slot Qt'nin temel fonksiyonlarından birtanesidir ve biraz daha farklısı diğer programlama dillerindede kullanılır. Özellikle .Net dillerinde. Signal Slot sayesinde program içinde nesneler birbirinden haberli çalışır ve daha komplex programları çıkarabiliriz.ÖNCELİKLE ŞUNU BELİRTEYİM UZUN BİR YAZI OLMASININ NEDENİ SIGNAL-SLOT KAVRAMININ QT İÇİN ÇOK FAZLA ÖNEMLİ OLMASIDIR. bUNU ÖĞRENDİĞİNİZDE QT PROGRAMINDA BİRÇOK ŞEYİ HALLETMİŞ OLACAKSINIZ
GUI programlamada bir nesne üzerinde bir değişiklik yaptığımızda başka bir nesnenin bundan haberi olması gerekir. Kısacası nesneler kendi arasında otomatik olarak haberleşsin. Örnek verecek olursak biz kapat butonuna tıklayınca formun close() fonksiyonu otomatik olarak çalışsın.
Diğer derleyici araçları bu işlem için pointer nesnesini kullanırlar ve pointer nesneside programlamayı zorlaştıran bir etkendir. Pointerlar ile kullandığımız nesnelerin artıkları diyelim onları temizlenmesi gerekir. Bunu bir yerde aksattığımızda programı yavaşlatacaktır. Burda ise pointer nesneleri otomatik olarak ,işlenir. Bu metod .Net uygulamalarındada başarılı bir şekilde uygulanmaktadır.
QT ile Signal Ve Slot Kullanımı
İşte QT Creator ile çalışan Signal Slot metodu: Bir nesne çalıştığında programa bir sinyal yayılır. Bu nesneler QTnin önceden tanımlanmış olan nesnelerdir, bizde qtnin sinyal fonksiyonlarına bizim kendi sinyal fonksiyonlarımızıda ekleyebiliriz. Slot ise bir fonksiyondur ve bu fonksiyon QT tarafından çağrılabilir fonksiyonlardandır. Qt nesneleri aynı sinyalleri gibi slotlarıda önceden tanımlanmıştır, aynı sinyaller gibi burdada biz kendimiz slot tanımlayabiliriz. Aslında yazdığımız herbir fonksiyon programdaki sinyal ve slottur da denebilir.
Bu metod en güvenli olanıdır. Çünkü işlemin çalışabilmesi için sinyalin ve slotun oluşma imzası aynı olmalıdır. (istisna olarak signal nesnesi değişkenler alabildiği için biraz daha uzun olabilir ama temelde aynı olmalıdır.) Bu sistem pointer temelli çalışan bir sistemdir ve sinyal lerin ve slotların eşleşmesini program bizim için yapar bu sayede pointer nesneleriyle biz uğraşmamış oluruz. Sinyal ve slot nesneleri birbirlerini program içerisinde string olarak algılarlar. Ve bulduklarında fonksiyonu çağırırlar. Sinyal ve slot fonksiyonları sınırsız sayıda parametre alabilir.
QObject veya QWidget classlarının altındaki bütün nesnelerde signal ve slot bulunmaktadır. Sinyaller nesnesinde herhangi bir değişiklik olduğu zaman yayılırlar. Mesela tıklama işlemi olunca yayılır. Bu diğer bütün nesnelere gider. nesnelerin o sinyali alıpalması önemli değildir. Eğer o nesnenin gelen sinyalle bir işi varsa o işi yapar yoksa bir işlem yapılmaz.
Slotlar alınan sinyallere göre çalışır, ve bunlar aynı zamanda birer fonksiyondur. Bu sinyal ve slot bağlantıları qt tarafından bağlanılmadığında çalışmazlar yani bağlantı olmalıdır.
Birçok sinyali tekbir slotada bağlayabileceğiniz gibi tek bir sinyalide birçok slota bağlayabilirsiniz. Ayrıca bir sinyali diğer bir sinyalede bağlamak mümkündür. Bu bir sinyal yayıldığında hemen diğer bir sinyalinde yayılamsını sağlar.
Bununla birlikte Signal Slot yapısı programlama sisteminide güçlendirir.
Signal Nedir?
Signal nesneleri program içindeki herhangi bir nesnenin anlık durumunun değişmesinden sonra programa yayılan nesnelerdir.Yani butona tıklamak bir signal durumudur. Signaller global bir nesne olduğu için programın heryerinden çağırılabilir, fakat onu olduğu classtan çağırmak en iyisidir.
Bir signal çalıştırıldığında ona bağlı olan slot fonksiyon normal bir fonksiyonmuş gibi hemen çalıştırılır. Bu olduğunda programlamaya uygun olarak işlem döngüsü başlamış olur. Bütün slotlar işlemini tamamladığında fonksiyonda tamamlanmış olur. Oluştururkenki söz dizimi biraz faklı olabilir fakat anlaşıldığında daha kolay olacaktır.
Eğer bir sinyale birden fazla slot bağlanmışsa , slotlar sırasıyla çalıştırılır. Sinyaller program tarafıdndan moc dosyalarında otomatik olarak oluşturulur ve .moc dosyalarında tutulur. Değer döndürmezler yani void tipi metodlardır.
Slot Nedir?
Slotlar ise kenidsine bağlı olan bir signal yayıldığında çalışan fonksiyondur. Slotlar bikldiğimiz C++ fonksiyonlarıdır ve normal şekilde çağrılabilirler onları özel yapan tek durum signallerin kendilerine bağlanmasıdır.
Slotlar normal C++ fonksiyonları oldukları için direk olarak çağrıldıklarında normal şekilde çalışırlar. Fakat, slot olarak çağrıldıklarında programın herhangi biryerinde çalışabilirler.
Bence bunları denemek için fonksiyonlar tanımlayın...
Signal Slot mekanizması direk olarak fonksiyonu çağırmaya göre biraz daha yavaştır. Fakat bununla birlikte çok esnek bir yapıdır.
Ayrıca Signal Slot yapısı Qt için oluşturulan bir yapıdır. Diğer derleyicilerde hata verebilir.
Aşağıdaki örnekleri QT nin kendi sitesinden aldım ordan anlatacağım
class Counter //Counter adında bir class oluşturuyorum
{
public:
Counter() { m_value = 0; }
int value() const { return m_value; }
void setValue(int value);
private:
int m_value;
};
#include //header dosyamız
class Counter : public QObject //Counter class nesnemin header nesnesi ve bunu QObject türünde tanımladığımızı belirtir
{
Q_OBJECT
public: //classtaki global değişkenler
Counter() { m_value = 0; }
int value() const { return m_value; }
public slots: //classtaki public türü slotlar
void setValue(int value); //classta olan fonksiyonum
signals: //classtaki signaller
void valueChanged(int newValue);
private: //classtaki private değişkenler
int m_value;
};
QObject tanımlamanın çok bir farkı yoktur QObject ile signal slot kullanabiliriz. Signal ve slot kullanan bütün classların en üstüne Q_OBJECT olarak tanımlamak gerekir. Bu durum QObject ile doğrudan veya dolaylı olarak bağlantılıdır. Slotları Programcının kendisi yazabilir. Counter::setValue() adlı slot örnek bir slot tanımlamasıdır.
void Counter::setValue(int value) //Counter ana class setValue ise alt fonksiyon(slottur)
{
if (value != m_value) {
m_value = value;
emit valueChanged(value); //emit ile fonksiyonu tekrar çalıştırdık
}
}
emit ile başlayan satırda valueChanged() signal nesnesini tekrardan çalıştırdık.
Aşağıdaki kod bloğunda connect komutuyla birincisinin valueChanged sinyalini ikincinin setValue fonksiyonuna bağladık
Counter a, b; // a ve b adında Counter nesnesini iki defa oluşturduk
QObject::connect(&a, &Counter::valueChanged, &b, &Counter::setValue); //ve valueChanged signalini setvalue slotuna bağladık
a.setValue(12);
b.setValue(48);
Burak Hamdi TUFAN
Comments