ปัญหาคือมีสองสัญญาณที่มีชื่อนั้น: QSpinBox::valueChanged(int)
และQSpinBox::valueChanged(QString)
. จาก Qt 5.7 มีฟังก์ชั่นตัวช่วยสำหรับเลือกโอเวอร์โหลดที่ต้องการเพื่อให้คุณสามารถเขียนได้
connect(spinbox, qOverload<int>(&QSpinBox::valueChanged),
slider, &QSlider::setValue);
สำหรับ Qt 5.6 และก่อนหน้าคุณต้องบอก Qt ว่าต้องการเลือกอันไหนโดยการแคสต์ให้ถูกประเภท:
connect(spinbox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
slider, &QSlider::setValue);
ฉันรู้ว่ามันน่าเกลียด แต่ไม่มีทางแก้ไขได้ บทเรียนวันนี้คืออย่าให้สัญญาณและช่องของคุณมากเกินไป!
ภาคผนวก : สิ่งที่น่ารำคาญจริงๆเกี่ยวกับนักแสดงคือสิ่งนั้น
- หนึ่งซ้ำชื่อคลาสสองครั้ง
- ต้องระบุค่าส่งคืนแม้ว่าโดยปกติจะเป็น
void
(สำหรับสัญญาณ)
บางครั้งฉันก็พบว่าตัวเองใช้ตัวอย่าง C ++ 11 นี้:
template<typename... Args> struct SELECT {
template<typename C, typename R>
static constexpr auto OVERLOAD_OF( R (C::*pmf)(Args...) ) -> decltype(pmf) {
return pmf;
}
};
การใช้งาน:
connect(spinbox, SELECT<int>::OVERLOAD_OF(&QSpinBox::valueChanged), ...)
ฉันเองพบว่ามันไม่มีประโยชน์จริงๆ ฉันคาดว่าปัญหานี้จะหายไปเองเมื่อผู้สร้าง (หรือ IDE ของคุณ) จะแทรกการแคสต์ที่ถูกต้องโดยอัตโนมัติเมื่อทำการเติม PMF โดยอัตโนมัติ แต่ในขณะเดียวกัน ...
หมายเหตุ: ไวยากรณ์การเชื่อมต่อที่ใช้ PMF ไม่ต้องการ C ++ 11 !
ภาคผนวก 2 : ในฟังก์ชันตัวช่วย Qt 5.7 ถูกเพิ่มเพื่อลดปัญหานี้โดยจำลองตามวิธีแก้ปัญหาของฉันข้างต้น ตัวช่วยหลักคือqOverload
(คุณมีqConstOverload
และqNonConstOverload
)
ตัวอย่างการใช้งาน (จากเอกสาร):
struct Foo {
void overloadedFunction();
void overloadedFunction(int, QString);
};
// requires C++14
qOverload<>(&Foo:overloadedFunction)
qOverload<int, QString>(&Foo:overloadedFunction)
// same, with C++11
QOverload<>::of(&Foo:overloadedFunction)
QOverload<int, QString>::of(&Foo:overloadedFunction)
ภาคผนวก 3 : หากคุณดูเอกสารของสัญญาณที่โอเวอร์โหลดตอนนี้วิธีแก้ปัญหาการโอเวอร์โหลดจะระบุไว้อย่างชัดเจนในเอกสาร ตัวอย่างเช่นhttps://doc.qt.io/qt-5/qspinbox.html#valueChanged-1พูดว่า
หมายเหตุ: ค่าสัญญาณเปลี่ยนเกินในคลาสนี้ ในการเชื่อมต่อกับสัญญาณนี้โดยใช้ไวยากรณ์ตัวชี้ฟังก์ชัน Qt มีตัวช่วยที่สะดวกในการรับตัวชี้ฟังก์ชันดังที่แสดงในตัวอย่างนี้:
connect(spinBox, QOverload<const QString &>::of(&QSpinBox::valueChanged),
[=](const QString &text){ /* ... */ });