Pada awalnya, Qt menggunakan fungsi pointer untuk menghubungkan sinyal ke slot. Contoh:
connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed);
Kelebihan menggunakan fungsi pointer adalah compiler dapat memeriksa apakah argumen signal kompatibel dengan argumen slot. Argumen juga dapat dikonversi secara implisit oleh compiler jika diperlukan.
Selain itu, Anda juga dapat menghubungkan sinyal ke functor atau lambda C++11:
connect(sender, &QObject::destroyed, this, [=](){ this->m_objects.remove(sender); });
Pada keduanya kasus, kami memberikan konteks (this
) dalam panggilan connect()
. Konteks tersebut menyediakan informasi tentang di mana receiver harus dieksekusi. Hal ini sangat penting, karena memberikan konteks memastikan bahwa receiver dieksekusi pada thread yang sesuai.
Lambda akan terhubung jika sender atau konteksnya dihancurkan. Anda harus berhati-hati agar objek yang digunakan dalam functor tetap hidup ketika signal diputar.
Menggunakan Macro SIGNAL dan SLOT
Cara lain untuk menghubungkan sinyal ke slot adalah dengan menggunakan macro SIGNAL
dan SLOT
. Aturan tentang apakah harus diisi atau tidak pada macro SIGNAL
dan SLOT
, jika argumen memiliki nilai default, adalah bahwa signature yang diterima oleh macro SIGNAL
tidak dapat memiliki argumen kurang dari signature yang diterima oleh macro SLOT
.
Contoh-contoh berikut akan bekerja:
connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(Qbject*)));
connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed()));
connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed()));
Namun contoh di bawah tidak akan bekerja:
connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed(QObject*)));
Karena slot akan menunggu QObject
yang signal tidak akan mengirim. Koneksi ini akan melaporkan kesalahan saat runtime.
Penggunaan Signal dan Slot pada Tingkat Lanjut
Untuk kasus-kasus di mana Anda memerlukan informasi tentang pengiriman sinyal, Qt menyediakan fungsi QObject::sender()
yang mengembalikan pointer ke objek yang mengirimkan sinyal.
Penggunaan Lambda untuk Mengirimkan Argument Ke Slot
Lambda expressions adalah cara mudah untuk mengirimkan argument custom ke slot:
connect(action, &QAction::triggered, engine,
[=]() { engine->processAction(action->text()); });
Menggunakan Qt dengan Signal dan Slot Pihak Ketiga
Bisa-bisa Anda ingin menggunakan Qt dengan mekanisme signal/slot pihak ketiga. Anda bahkan dapat menggunakannya dalam proyek yang sama. Untuk melakukan itu, tulis sebagai berikut ke dalam file CMake project:
target_compile_definitions(my_app PRIVATE QT_NO_KEYWORDS)
Atau jika Anda menggunakan qmake, tulis sebagai berikut ke dalam file .pro:
QT += no_keywords
Hal ini memperingatkan Qt tidak untuk mendefinisikan keyword signals
, slots
, dan emit
karena nama-nama tersebut akan digunakan oleh library pihak ketiga, misalnya Boost. Kemudian Anda dapat terus menggunakan signal dan slot Qt dengan flag no_keywords
.
Signal dan Slot pada Libray Qt-based
API publik dari libray Qt-based harus menggunakan keyword Q_SIGNALS
dan Q_SLOTS
alih-alih signals
dan slots
. Jika tidak, maka sulit untuk menggunakannya dalam proyek yang memiliki flag QT_NO_KEYWORDS
.
Untuk meneguhkan restriksi ini, pembuat library dapat mengatur define preprocessor QT_NO_SIGNALS_SLOTS_KEYWORDS
saat membangun library.
Menggunakan Signal dan Slot Qt dengan Callback C++
Saya memiliki program yang sebelumnya diimplementasikan menggunakan framework Qt dengan signal & slot. Namun, karena beberapa kebutuhan, saya harus membagi program menjadi dua bagian: 1-Library, yang berupa c++ biasa, independen dari software lain dan 2-Aplikasi GUI, yang terhubung dengan library (1) dan dapat memiliki dependensi pada Qt.
Maka saya perlu memperbarui beberapa kelas asli dari signal/slot dan menggantinya dengan callback C++.
Referensi
Qt Documentation: Signals and Slots
Markdown Documentation: Markdown Syntax