Garis-Garis Penting dalam Penggunaan Signals dan Slots di Qt

Garis-Garis Penting dalam Penggunaan Signals dan Slots di Qt

Qt memberikan fitur canggih dalam bentuk signals dan slots, yang memungkinkan programmer untuk membuat aplikasi yang lebih interaktif dan dapat berkomunikasi dengan baik. Dalam artikel ini, kita akan membahas tentang bagaimana menggunakan signals dan slots di Qt.

Slot: Fungsi Penerima

Sebuah slot adalah fungsi penerima yang digunakan untuk mendapatkan informasi tentang perubahan status pada widget lain. Contohnya, LCD Number menggunaan slot display() untuk menampilkan bilangan yang sesuai. Karena display() adalah bagian dari interface kelas dengan program lainnya, maka slot tersebut harus public.

Beberapa contoh program Qt menghubungkan signal valueChanged() dari QScrollBar ke slot display(), sehingga LCD number terus menampilkan nilai scrollbar.

Signals dan Slots dengan Argumen Default

Signatures signals dan slots dapat berisi argumen, dan argumen dapat memiliki nilai default. Contohnya, QObject::destroyed():

void destroyed(QObject* = nullptr);

Ketika sebuah QObject dihapus, ia akan mengemiti signal ini. Kita ingin menangkap signal tersebut di mana pun kita memiliki referensi yang tidak sah ke JObject yang dihapus, sehingga kita dapat membersihkan nya. Sebuah slot dengan signature seperti berikut dapat digunakan:

void objectDestroyed(QObject* obj = nullptr);

Untuk menghubungkan signal dan slot, kita menggunakan QObject::connect(). Ada beberapa cara untuk menghubungkan signal dan slots. Pertama, kita menggunakan function pointers:

connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed);

Ada beberapa kelebihan dalam penggunaan QObject::connect() dengan function pointers. Pertama, ia memungkinkan compiler untuk memeriksa bahwa argumen signal adalah kompatibel dengan argumen slot. Argumen juga dapat di konversi secara otomatis oleh compiler jika diperlukan.

Kita juga dapat menghubungkan ke functors atau lambdas C++11:

connect(sender, &QObject::destroyed, this, [=](){ this->m_objects.remove(sender); });

Dalam kedua kasus ini, kita memberikan context this dalam panggilan connect(). Context objek memberikan informasi tentang thread mana receiver harus dieksekusi. Hal ini penting, karena memberikan context memungkinkan receiver untuk dieksekusi dalam thread yang sesuai.

Penggunaan Signals dan Slots Lanjutan

Ada beberapa cara lain untuk menghubungkan signal dan slots di Qt. Kita dapat menggunakan QObject::connect() dengan macro SIGNAL() dan SLOT():

connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(Qbject*)));

Namun, perlu diingat bahwa signal dan slot argumen tidak diperiksa oleh compiler jika penggunaan overload ini.

Penggunaan Signals dan Slots yang Lebih Lanjut

Untuk kasus-kasus di mana kita memerlukan informasi tentang siapa yang mengirimkan signal, Qt memberikan fungsi QObject::sender(), yang kembali pointer ke objek yang mengirimkan signal.

Lambdas adalah cara yang mudah untuk melewati argumen custom ke slot:

connect(action, &QAction::triggered, engine,
 [=]() { engine->processAction(action->text()); });

Penggunaan Signals dan Slots dengan Library Ketiga

Mungkin kita dapat menggunakan Qt dengan mekanisme signal/slot ketiga. Kita dapat bahkan menggunakan dua mekanisme tersebut dalam proyek yang sama. Untuk melakukannya, kita perlu menulis dalam file CMake project:

target_compile_definitions(my_app PRIVATE QT_NO_KEYWORDS)

atau dalam file .pro qmake:

QT += no_keywords

Hal ini berarti bahwa Qt tidak akan mendefinisikan keyword moc untuk signal, slots, dan emit, karena nama-nama tersebut akan digunakan oleh library ketiga, misalnya Boost. Kemudian kita dapat terus menggunakan signals dan slots Qt dengan flag no_keywords.

Signals dan Slots di Library Qt-based

API publik dari library Qt-based harus menggunakan keyword Q_SIGNALS dan Q_SLOTS alih-alih signals dan slots. Jika tidak, maka sangat sulit untuk menggunakan library tersebut dalam proyek yang mendefinisikan QT_NO_KEYWORDS.

Untuk mengatasi masalah ini, pengembang library dapat menulis define preprocessor QT_NO_SIGNALS_SLOTS_KEYWORDS saat membangun library. Define ini akan menghapus signal dan slots tanpa mengganggu penggunaan keyword lainnya di Qt.