Menggunakan Function Pointers dalam Qt Signal dan Slot

Menggunakan Function Pointers dalam Qt Signal dan Slot

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