Vấn đề ở đây là có hai tín hiệu với tên đó: QSpinBox::valueChanged(int)
và QSpinBox::valueChanged(QString)
. Từ Qt 5.7, có các hàm trợ giúp được cung cấp để chọn quá tải mong muốn, do đó bạn có thể viết
connect(spinbox, qOverload<int>(&QSpinBox::valueChanged),
slider, &QSlider::setValue);
Đối với Qt 5.6 trở về trước, bạn cần cho Qt biết bạn muốn chọn loại nào, bằng cách chuyển nó sang đúng loại:
connect(spinbox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
slider, &QSlider::setValue);
Tôi biết, nó xấu . Nhưng không có cách nào khác. Bài học hôm nay là: đừng quá tải tín hiệu và khe cắm của bạn!
Phụ lục : điều thực sự khó chịu về dàn diễn viên là
- một lần lặp lại tên lớp hai lần
- người ta phải chỉ định giá trị trả về ngay cả khi nó thường
void
(đối với tín hiệu).
Vì vậy, đôi khi tôi đã thấy mình sử dụng đoạn trích C ++ 11 này:
template<typename... Args> struct SELECT {
template<typename C, typename R>
static constexpr auto OVERLOAD_OF( R (C::*pmf)(Args...) ) -> decltype(pmf) {
return pmf;
}
};
Sử dụng:
connect(spinbox, SELECT<int>::OVERLOAD_OF(&QSpinBox::valueChanged), ...)
Cá nhân tôi thấy nó không thực sự hữu ích. Tôi hy vọng vấn đề này sẽ tự biến mất khi Creator (hoặc IDE của bạn) sẽ tự động chèn đúng cast khi tự động hoàn thành thao tác lấy PMF. Nhưng trong khi đó ...
Lưu ý: cú pháp kết nối dựa trên PMF không yêu cầu C ++ 11 !
Phụ lục 2 : trong các chức năng của trình trợ giúp Qt 5.7 đã được thêm vào để giảm thiểu điều này, được mô phỏng theo cách giải quyết của tôi ở trên. Người trợ giúp chính là qOverload
(bạn cũng đã có qConstOverload
và qNonConstOverload
).
Ví dụ sử dụng (từ các tài liệu):
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)
Phụ lục 3 : nếu bạn xem tài liệu về bất kỳ tín hiệu quá tải nào, thì bây giờ giải pháp cho vấn đề quá tải được nêu rõ trong chính các tài liệu. Chẳng hạn, https://doc.qt.io/qt-5/qspinbox.html#valueChanged-1 nói
Lưu ý: Giá trị tín hiệu Thay đổi bị quá tải trong lớp này. Để kết nối với tín hiệu này bằng cách sử dụng cú pháp con trỏ hàm, Qt cung cấp một trình trợ giúp thuận tiện để lấy con trỏ hàm như trong ví dụ này:
connect(spinBox, QOverload<const QString &>::of(&QSpinBox::valueChanged),
[=](const QString &text){ /* ... */ });