Saat menjalankan aplikasi dengan antarmuka berjendela, penting untuk memastikan tidak ada pembekuan. Untuk ini, perhitungan kompleks harus dijalankan dalam utas terpisah. Konsep aplikasi multi-threaded berjalan baik dengan pendekatan slot sinyal Qt, tanpa perlu mendefinisikan ulang metode run ().
Ide utama. Dalam aplikasi multi-threaded, perhitungan dilakukan dalam utas terpisah, pada akhirnya sinyal dipancarkan, mentransmisikan hasilnya dalam argumennya. Sebuah slot yang sudah dimiliki oleh MainWindow akan dipanggil. Hasil perhitungan akan menjadi argumen slot dan tidak akan sulit untuk menghasilkannya.
Menggambar analogi dengan mikrokontroler, sinyal adalah transisi sepanjang vektor interupsi, dan slot adalah interrupt handler itu sendiri. Agar "interupsi" terjadi, sinyal harus dipancarkan: emit mysignalvoid (); maka Qt akan mulai mencarinya dengan "handler" (slot). Di Qt, Anda dapat menggantung banyak slot pada satu sinyal.
Gambar berikut menunjukkan algoritma aplikasi demo. Utas pemrosesan setiap detik menginterogasi menurut legenda perangkat USB HID. Kemudian sinyal memancarkan, yang memproses slot yang sudah menjadi milik MainWindow dan yang sesuai memiliki kemampuan untuk menggambar pada formulir.

Jadi, kami memiliki kelas yang dapat menggunakan pendekatan slot sinyal. Untuk melakukan ini, deklarasi mereka menggunakan makro Q_OBJECT.
class Worker : public QObject { Q_OBJECT
Untuk melewati hasil perhitungan dalam argumen, perlu
mendaftarkan jenis yang digunakan untuk argumen. Anda bisa melakukan ini di tempat yang berbeda, tetapi biasanya di konstruktor kelas, yang kemudian akan bekerja dengan tipe ini:
Worker::Worker(){ qRegisterMetaType<std::size_t>("size_t"); qRegisterMetaType<uint8_t const *>("uint8_t const *");
Selanjutnya, timer dibuat di konstruktor dari thread pemrosesan. Setiap detik, slot pemrosesan updateUSBDataCallback akan dipanggil. Perhatikan sintaks koneksi slot sinyal di Qt5.
this->timerDeviceRead = new QTimer(); connect(Worker::timerDeviceRead, &QTimer::timeout, this, &Worker::updateUSBDataCallback); this->timerDeviceRead->start();
Berikut ini adalah badan slot pemrosesan. Semua kode lama harus ada di sini.
void Worker::updateUSBDataCallback(){ size_t mysize = 65; uint8_t buf[65] = { "I like USB HID" }; emit GuiUpdatePlease(buf,mysize);
Untuk mendemonstrasikan di sini, segera setelah sinyal dipancarkan ke slot MainWindow, konten array secara berani dimodifikasi. Dan karena array dilewatkan oleh pointer, pembacaan kotor diperoleh. Untuk mencegah situasi ini, sinyal dari utas pemrosesan harus terhubung ke slot GuiUpdateCallback () dengan cara tertentu:
MainWindow::MainWindow{ connect(worker, &Worker::GuiUpdatePlease, this, &MainWindow::GuiUpdateCallback, Qt::BlockingQueuedConnection);
Dalam hal ini, memancarkan sinyal, utas pemrosesan diblokir hingga akhir slot GuiUpdateCallback ().
Jika "uint8_t const *" lama membingungkan Anda dalam teks program, maka Anda bisa mendapatkan sinonim TU8PTR:
typedef uint8_t const * TU8PTR;
Kode sumber