Saya mengalami masalah untuk memahami sintaks sinyal / slot baru (menggunakan fungsi pointer ke anggota) di Qt 5, seperti yang dijelaskan dalam Sintaks Slot Sinyal Baru . Saya mencoba mengubah ini:
QObject::connect(spinBox, SIGNAL(valueChanged(int)),
slider, SLOT(setValue(int));
untuk ini:
QObject::connect(spinBox, &QSpinBox::valueChanged,
slider, &QSlider::setValue);
tapi saya mendapatkan kesalahan saat mencoba mengompilasinya:
kesalahan: tidak ada fungsi yang cocok untuk panggilan ke
QObject::connect(QSpinBox*&, <unresolved overloaded function type>, QSlider*&, void (QAbstractSlider::*)(int))
Saya sudah mencoba dengan dentang dan gcc di Linux, keduanya dengan -std=c++11
.
Apa yang saya lakukan salah, dan bagaimana saya bisa memperbaikinya?
Jawaban:
Masalahnya di sini adalah bahwa ada dua sinyal dengan nama itu:
QSpinBox::valueChanged(int)
danQSpinBox::valueChanged(QString)
. Dari Qt 5.7, ada fungsi pembantu yang disediakan untuk memilih kelebihan yang diinginkan, sehingga Anda dapat menulisUntuk Qt 5.6 dan sebelumnya, Anda perlu memberi tahu Qt mana yang ingin Anda pilih, dengan melemparkannya ke jenis yang tepat:
Saya tahu, itu jelek . Tapi tidak ada jalan lain untuk ini. Pelajaran hari ini adalah: jangan membebani sinyal dan slot Anda!
Tambahan : apa yang benar-benar mengganggu tentang para pemain adalah itu
void
(untuk sinyal).Jadi saya kadang menemukan diri saya menggunakan cuplikan C ++ 11 ini:
Pemakaian:
Saya pribadi merasa itu tidak terlalu berguna. Saya berharap masalah ini hilang dengan sendirinya ketika Creator (atau IDE Anda) akan secara otomatis memasukkan gips yang tepat ketika secara otomatis menyelesaikan operasi pengambilan PMF. Namun sementara itu ...
Catatan: sintaks koneksi berbasis PMF tidak memerlukan C ++ 11 !
Tambahan 2 : dalam Qt 5.7 fungsi pembantu ditambahkan untuk mengurangi ini, dimodelkan setelah solusi saya di atas. Pembantu utama adalah
qOverload
(Anda juga punyaqConstOverload
danqNonConstOverload
).Contoh penggunaan (dari dokumen):
Tambahan 3 : jika Anda melihat dokumentasi dari setiap sinyal kelebihan beban, sekarang solusi untuk masalah kelebihan muatan tersebut dinyatakan dengan jelas dalam dokumen itu sendiri. Misalnya, https://doc.qt.io/qt-5/qspinbox.html#valueChanged-1 kata
sumber
static_cast
keburukan daripada sintaks lama, hanya karena sintaks baru memungkinkan pemeriksaan waktu kompilasi untuk keberadaan sinyal / slot di mana sintaks lama akan gagal saat runtime.QSerialPort
)Pesan kesalahan adalah:
Bagian penting dari ini adalah penyebutan " tipe fungsi kelebihan beban yang tidak terselesaikan ". Kompiler tidak tahu apakah maksud Anda
QSpinBox::valueChanged(int)
atauQSpinBox::valueChanged(QString)
.Ada beberapa cara untuk mengatasi kelebihan:
Berikan parameter templat yang cocok untuk
connect()
Ini memaksa
connect()
untuk menyelesaikan&QSpinBox::valueChanged
kelebihan yang dibutuhkanint
.Jika Anda memiliki kelebihan berlebih yang belum terselesaikan untuk argumen slot, maka Anda harus menyediakan argumen templat kedua
connect()
. Sayangnya, tidak ada sintaks untuk meminta yang pertama disimpulkan, jadi Anda harus menyediakan keduanya. Saat itulah pendekatan kedua dapat membantu:Gunakan variabel sementara dari jenis yang benar
Tugas untuk
signal
akan memilih kelebihan yang diinginkan, dan sekarang dapat diganti dengan sukses ke dalam templat. Ini berfungsi sama baiknya dengan argumen 'slot', dan saya merasa kurang rumit dalam kasus itu.Gunakan konversi
Kita dapat menghindari di
static_cast
sini, karena itu hanya paksaan alih-alih menghapus perlindungan bahasa. Saya menggunakan sesuatu seperti:Ini memungkinkan kita untuk menulis
sumber
Sebenarnya, Anda bisa membungkus slot Anda dengan lambda dan ini:
akan terlihat lebih baik. : \
sumber
Solusi di atas berfungsi, tetapi saya memecahkan ini dengan cara yang sedikit berbeda, menggunakan makro, Jadi untuk berjaga-jaga di sini adalah:
Tambahkan ini dalam kode Anda.
Lalu, contoh Anda:
Menjadi:
sumber
#define CONNECTCAST(class,fun,args) static_cast<void(class::*)args>(&class::fun)
- digunakan sepertiCONNECTCAST(QSpinBox, valueChanged, (double))
dalam kasus ini.