Qt menyediakan fitur yang disebut "signals" dan "slots" untuk mengizinkan komunikasi antar objek. Dalam artikel ini, kita akan membahas penggunaan lanjutan dari signals dan slots dalam Qt.
Menggunakan Slot
Slot adalah fungsi yang menerima informasi tentang perubahan status pada widget lainnya. LcdNumber menggunakan slot untuk menampilkan angka yang dipilih. Fungsi display()
merupakan bagian dari interface antara objek dengan program lain, sehingga slot-nya harus publik.
Beberapa contoh program Qt menghubungkan signal valueChanged()
dari QScrollBar ke slot display()
, sehingga LCD number akan menampilkan nilai dari scrollbar secara terus-menerus. Perlu diingat bahwa fungsi display()
memiliki overload; Qt akan memilih versi yang sesuai ketika Anda menghubungkan signal ke slot.
Signals dan Slots dengan Argumen Lembur
Tanda tangan signal dan slot dapat berisi argumen, dan argumen dapat memiliki nilai default. Contoh adalah signala destroyed()
dalam kelas QObject
:
void destroyed(QObject* = nullptr);
Ketika objek QObject
dihapus, ia akan mengemiti signala ini. Kita ingin menangkap signala ini di mana pun kita memiliki referensi yang tidak valid ke objek yang dihapus, sehingga kita dapat membersihkannya. Suatu slot dengan nama objectDestroyed()
mungkin berisi:
void objectDestroyed(QObject* obj = nullptr);
Untuk menghubungkan signal ke slot, kita menggunakan fungsi QObject::connect()
. Ada beberapa cara untuk menghubungkan signal dan slot. Cara pertama adalah dengan menggunakan pointer fungsi:
connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed);
Ada beberapa kelebihan dari menggunakan QObject::connect()
dengan pointer fungsi. Pertama, compiler dapat memeriksa bahwa argumen signal-nya sesuai dengan argumen slot-nya. Argumen juga dapat diubah secara implicit oleh compiler jika diperlukan.
Kita juga dapat menghubungkan signal ke funktor atau lambda C++11:
connect(sender, &QObject::destroyed, this, [=](){ this->m_objects.remove(sender); });
Dalam keduanya kasus, kita memberikan this
sebagai konteks dalam panggilan connect()
. Konteks objek memberikan informasi tentang thread mana yang harus digunakan untuk menerima objek. Hal ini penting, karena memberikan konteks objek memastikan bahwa objek akan diproses dalam thread yang sama.
Menggunakan SIGNAL dan SLOT
Cara lain untuk menghubungkan signal ke slot adalah dengan menggunakan QObject::connect()
dan makro SIGNAL
dan SLOT
. Aturan tentang apakah harus termasuk argumen atau tidak dalam makro SIGNAL
dan SLOT
, jika argumen memiliki nilai default, adalah bahwa tanda tangan yang dipakai dalam makro SIGNAL
tidak dapat kurang dari tanda tangan yang dipakai dalam makro SLOT
.
Semua contoh di atas akan berfungsi:
connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(Qbject*)));
Namun contoh ini tidak akan bekerja:
connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed(Qbject*)));
…karena slot-nya akan menunggu objek QObject
yang signal tidak akan kirimkan. Koneksi ini akan melaporkan error saat runtime.
Perlu diingat bahwa argumen signal dan slot tidak diperiksa oleh compiler ketika menggunakan overload QObject::connect()
.
Penggunaan Lanjutan Signals dan Slots
Untuk kasus-kasus yang memerlukan informasi tentang pengirim signala, Qt menyediakan fungsi QObject::sender()
, yang mengembalikan pointer ke objek yang mengemiti signala.
Lambda expressions adalah cara yang praktis untuk melewati argumen khusus ke slot:
connect(action, &QAction::triggered, engine,
[=]() { engine->processAction(action->text()); });
Menggunakan Qt dengan Signal dan Slot Pihak Ketiga
Mungkin Anda dapat menggunakan Qt dengan signal/slot mechanism pihak ketiga. Anda bahkan dapat menggunakannya dalam proyek yang sama. Untuk melakukannya, tulis kode berikut ke file CMake proyek:
target_compile_definitions(my_app NAME)
Namun demikian, penggunaan signal dan slot pihak ketiga memerlukan keterampilan lebih lanjut dan pengetahuan tentang bagaimana mengintegrasikan dengan Qt.
Dalam artikel ini, kita telah membahas penggunaan lanjutan dari signals dan slots dalam Qt. Dengan menggunakan fitur-fitur ini, Anda dapat menciptakan aplikasi yang lebih interaktif dan efektif.