Katakanlah saya memiliki sinyal ini:
signals:
void progressNotification(int progress);
Saya baru saja mengetahui tentang kata kunci emit di Qt. Sampai sekarang, saya biasa mengeksekusi sinyal hanya dengan memanggilnya seperti fungsi biasa. Jadi, alih-alih:
emit progressNotification(1000 * seconds);
Saya akan menulis:
progressNotification(1000 * seconds);
Memanggil mereka seperti itu sepertinya berhasil, dan semua slot yang terhubung akan dijalankan, jadi apakah menggunakan kata kunci emit menyebabkan perilaku yang berbeda, atau apakah itu hanya gula sintaksis?
emit
tidak dibutuhkan. Anehnya, Anda mengetahuiemit
lama setelah memanggil sinyal secara langsung, karena sistem slot sinyal adalah salah satu hal pertama yang harus dipelajari tentang Qt.Jawaban:
emit
hanyalah gula sintaksis. Jika Anda melihat output pra-proses dari fungsi yang memancarkan sinyal, Anda akan melihat bahwa fungsiemit
tersebut hilang begitu saja."Ajaib" terjadi dalam kode yang dihasilkan untuk fungsi pemancar sinyal, yang dapat Anda lihat dengan memeriksa kode C ++ yang dihasilkan oleh moc.
Misalnya
foo
sinyal tanpa parameter menghasilkan fungsi anggota ini:Dan kode
emit foo();
tersebut diproses sebelumnya menjadi sederhanafoo();
emit
didefinisikan dalamQt/qobjectdefs.h
(bagaimanapun juga dalam ragam sumber terbuka dari sumber), seperti ini:(Define guard memungkinkan Anda untuk menggunakan Qt dengan framework lain yang memiliki nama yang bertabrakan melalui
no_keywords
opsi konfigurasi QMake.)sumber
emit
yang benar-benar melakukan lebih dari tidak sama sekali? Saya menemukan bahwa memiliki 'gula sintaksis' dalam hal ini hanya membingungkan pemula (atau setidaknya saya ketika saya adalah pengguna Qt pemula) - tampaknya sesuatu yang ajaib atau penting terjadi denganemit
kata kunci pseudo, ketika tidak melakukan apa-apa pada semua - semua keajaiban terjadi dalam fungsi lama biasa yangmoc
menciptakan (moc
adalah keajaiban untuk sinyal dan slot Qt).emit
adalah dekorasi tak perlu yang tidak melakukan apa pun kecuali penting.emit
memberi tahu orang yang membaca panggilan bahwa keajaiban akan segera terjadi (yaitu ini akan memicu kode dalam objek yang mungkin tidak pernah didengar kelas ini, dan panggilan ini mungkin sinkron atau asinkron), yang pada dasarnya akan hilang total jika Anda menghilangkan kata kunci. Gunakan. Ini mendokumentasikan otomatis. "Pemula" harus membaca dokumen & tutorial, danemit
selalu ada (bagaimanapun juga di dokumen resmi). Menemukan bahwa Anda bisa memanggil fungsi itu harus terjadi setelah Anda "melihat cahaya" - Anda bukan pemula lagi pada saat itu.emit
'kata kunci' itu. Saya pikir saya lebih suka bahwa konvensi penamaan digunakan jika ada kebutuhan untuk memperjelas bahwa panggilan fungsi adalah sinyal.emit
.emit
psuedo-kata kunci-komentar adalah untuk menjelaskan bahwa sinyal sedang dipanggil, maka konvensi penamaan dapat melakukan hal yang sama, tanpa misteri dan dengan manfaat serupa. Konvensi penamaan tidak dapat diberlakukan oleh Qt (sebenarnya,moc
dapat menegakkannya - tetapi saya juga tidak menganjurkan itu), tetapi Qt tidak dapat memaksakan penggunaanemit
keduanya. Dan sementara Anda dapat 'mematikan'emit
jika ada bentrokan nama, itu tidak banyak membantu jika Anda memiliki banyak file sumber yang menggunakannya (tidak perlu, untuk boot).Setelah 18 bulan ... Saya mulai dengan komentar di bawah jawaban @ Mat, dan segera kehabisan ruangan. Demikian jawabannya.
IMO
emit
bukanlah gula sintaksis atau kata kunci sederhana dalam arti ituconnect
mekanisme mengenali bahwa memang itu adalahsignal
, danSeluruh sistem sinyal / slot adalah idiom yang berbeda dari pemanggilan fungsi sederhana. Saya percaya itu berasal dari pola pengamat. Ada juga perbedaan besar antara a
signal
dan aslot
: sinyal tidak harus diimplementasikan, sedangkan slot harus !Anda sedang berjalan di jalan dan melihat sebuah rumah terbakar (sebuah sinyal). Anda menghubungi 911 ( hubungkan sinyal api dengan slot respons 911 ). Sinyalnya hanya dipancarkan , sedangkan slotnya diimplementasikan oleh pemadam kebakaran. Mungkin tidak tepat, tetapi Anda mengerti. Mari kita lihat contoh OP.
Beberapa objek backend mengetahui seberapa banyak kemajuan yang telah dibuat. Jadi itu hanya bisa
emit progressNotification(...)
memberi sinyal. Terserah kelas yang menampilkan bilah kemajuan yang sebenarnya, untuk mengambil sinyal ini dan menjalankannya. Tapi bagaimana pandangan terhubung ke sinyal ini? Selamat datang di sistem sinyal / slot Qt. Seseorang sekarang dapat membayangkan kelas manajer (biasanya semacam widget), yang terdiri dari objek tampilan dan objek komputasi data (keduanyaQObjects
), dapat berfungsiconnect (m_myDataEngine, &DataEngine::progressNotification, m_myViewObj, &SimpleView::displayProgress)
.Mari kita tidak membahas aspek desain kelas manajer, tetapi cukup untuk mengatakan bahwa di sinilah sistem sinyal / slot bersinar. Saya dapat fokus untuk merancang arsitektur yang sangat bersih untuk aplikasi saya. Tidak selalu, tetapi sering kali, saya menemukan bahwa saya hanya memancarkan sinyal tetapi menerapkan slot .
Jika dimungkinkan untuk menggunakan / memanggil metode sinyal tanpa pernah memancarkannya , maka itu berarti bahwa Anda tidak pernah membutuhkan fungsi itu sebagai sinyal sejak awal.
sumber
emit
memang hanya makro kosong dan murni opsional. Tidak begitu juga dengan kata kuncisignal
danslot
yang diproses oleh moc.signal
digunakan untuk menyediakan fungsi implementasi,slot
digunakan untuk membuat entri objek meta sehingga ditemukan denganSLOT(MySlot())
makro atau di QML.emit
adalah suggar sintaksis. Tidak ada yang akan mengeluh jika Anda menulisemit i++;
(tetapi mungkin rekan kerja Anda) dan Anda masih tidak dapat terhubungi++
.Pilihan kedua akan menyiratkan bahwa Anda selalu tahu apa nama fungsi dan parameter fungsi dan bahwa objek yang Anda kirimi diketahui oleh fungsi tersebut. Kedua kasus tersebut tidak selalu benar, jadi itulah dua hal utama mengapa slot dan sinyal dibuat. "under-the-hood" sinyal dan mekanisme slot hanyalah sebuah meja dengan penunjuk ke setiap fungsi yang terhubung.
Juga, lihat pdf ini yang menjelaskan dengan sangat jelas sifat dari sinyal dan mekanisme slot: http://www.elpauer.org/stuff/a_deeper_look_at_signals_and_slots.pdf
sumber
emit
itu hanya no-op. Tetapi bahkan dalam kasus ini membaca badan pertanyaan seharusnya sudah membereskan semuanya, jadi -1.