Dalam Qt, signal dan slot adalah fitur yang memungkinkan Anda untuk berkomunikasi antara objek yang terpisah. Signal adalah fungsi yang dapat diemitsi oleh objek dan diterima oleh slot. Slot adalah fungsi yang dipanggil ketika signal dilepas.
Dalam contoh di atas, LcdNumber menggunakan slot display()
untuk menampilkan angka yang dikirimkan melalui signal valueChanged()
. Karena display()
adalah bagian dari interface antara objek LcdNumber dan program lainnya, maka slot display()
harus dibuat sebagai fungsi publik.
Banyak contoh program Qt menghubungkan signal valueChanged()
dari QScrollBar ke slot display()
sehingga LCD number terus menampilkan nilai scrollbar.
Perlu diingat bahwa slot display()
adalah overridden; Qt akan memilih versi yang sesuai ketika Anda menghubungkan signal ke slot. Dengan callbacks, Anda harus menemukan lima nama yang berbeda dan menjaga tipe data sendiri.
Signal dan Slot dengan Argumen Default
Signature dari signal dan slot dapat memiliki argumen, dan argumen dapat memiliki nilai default. Pertimbangkan QObject::destroyed()
:
void destroyed(QObject* = nullptr);
Ketika sebuah objek QObject dihapus, maka signal ini dilepas. Kita ingin mencapai signal ini, di mana saja kita memiliki referensi sementara ke objek yang dihapus, sehingga kita dapat membersihkan.
Sebuah slot signature yang sesuai mungkin adalah:
void objectDestroyed(QObject* obj = nullptr);
Untuk menghubungkan signal ke slot, kita menggunakan QObject::connect()
. Ada beberapa cara untuk menghubungkan signal dan slot. Cara pertama adalah dengan menggunakan function pointers:
connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed);
Ada beberapa kelebihan menggunakan QObject::connect()
dengan function pointers. Pertama, ia memungkinkan compiler untuk memeriksa bahwa argumen signal kompatibel dengan argumen slot. Argumen juga dapat dikonversi secara implisit oleh compiler jika diperlukan.
Anda juga dapat menghubungkan ke functors atau lambda C++11:
connect(sender, &QObject::destroyed, this, [=](){ this->m_objects.remove(sender); });
Dalam kedua kasus ini, kita memberikan this
sebagai konteks dalam panggilan ke connect()
. Konteks objek menyediakan informasi tentang thread di mana receiver harus dieksekusi. Ini penting, karena memastikan bahwa receiver dieksekusi dalam thread konteks.
Lambda akan terpisah ketika sender atau konteks dihapus. Anda harus berhati-hati bahwa objek yang digunakan di dalam functor masih hidup ketika signal dilepas.
Cara lain untuk menghubungkan signal ke slot adalah dengan menggunakan QObject::connect()
dan macros SIGNAL dan SLOT. Aturan tentang apakah termasuk argumen atau tidak dalam macros SIGNAL() dan SLOT(), jika argumen memiliki nilai default, adalah bahwa signature yang dipakai di dalam macros SIGNAL() harus tidak memiliki argumen yang lebih sedikit daripada signature yang dipakai di dalam macros SLOT().