问题
According to the QT5 docs, the QRadioButton inherits the 4 signals from QAbstractButton, which includes the clicked signal. The template for it is clicked(bool checked = false)
so I'm confused why this code returns a long error message, part of which is error: static assertion failed: Signal and slot arguments are not compatible
.
Code (Simplified, may contain mistakes that are not part of the original):
#include <QApplication>
#include <QMainWindow>
#include <QRadioButton>
#include <iostream>
class front_end : public QWidget
{
Q_OBJECT
public:
void load()
{
auto *rbtn_0 = new QRadioButton(tr("Reference"), this);
rbtn_0->setChecked(true);
QObject::connect(rbtn_0, &QRadioButton::clicked, this, SLOT(rbtn_toggle(bool)));
}
public slots:
void rbtn_toggle(bool arg_0)
{
std::cout << "Toggle\n";
}
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
front_end FrontEnd;
FrontEnd.load();
return app.exec();
}
Compiled with:
qmake -project -norecursive -Wall -Wparser -o main.pro;
echo "QT += widgets" >> main.pro;
echo "CONFIG += c++11" >> main.pro;
qmake -norecursive main.pro;
make;
Error Message:
g++ -c -m64 -pipe -O2 -std=c++0x -Wall -W -D_REENTRANT -fPIE -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++-64 -I. -I. -I/usr/include/qt5 -I/usr/include/qt5/QtWidgets -I/usr/include/qt5/QtGui -I/usr/include/qt5/QtCore -I. -o main.o main.cpp
main.cpp:21:8: warning: unused parameter ‘arg_0’ [-Wunused-parameter]
void rbtn_toggle(bool arg_0)
^
In file included from /usr/include/qt5/QtCore/qcoreapplication.h:48:0,
from /usr/include/qt5/QtWidgets/qapplication.h:45,
from /usr/include/qt5/QtWidgets/QApplication:1,
from main.cpp:1:
/usr/include/qt5/QtCore/qobject.h: In instantiation of ‘static typename QtPrivate::QEnableIf<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == (-1)), QMetaObject::Connection>::Type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const QObject*, Func2, Qt::ConnectionType) [with Func1 = void (QAbstractButton::*)(bool); Func2 = const char*; typename QtPrivate::QEnableIf<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == (-1)), QMetaObject::Connection>::Type = QMetaObject::Connection; typename QtPrivate::FunctionPointer<Func>::Object = QAbstractButton]’:
main.cpp:17:83: required from here
/usr/include/qt5/QtCore/qobject.h:300:122: warning: overflow in implicit constant conversion [-Woverflow]
const int FunctorArgumentCount = QtPrivate::ComputeFunctorArgumentCount<Func2 , typename SignalType::Arguments>::Value;
^
In file included from /usr/include/qt5/QtCore/qcoreapplication.h:45:0,
from /usr/include/qt5/QtWidgets/qapplication.h:45,
from /usr/include/qt5/QtWidgets/QApplication:1,
from main.cpp:1:
/usr/include/qt5/QtCore/qglobal.h:669:47: error: static assertion failed: Signal and slot arguments are not compatible.
#define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message)
^
/usr/include/qt5/QtCore/qobject.h:302:9: note: in expansion of macro ‘Q_STATIC_ASSERT_X’
Q_STATIC_ASSERT_X((FunctorArgumentCount >= 0),
^
In file included from /usr/include/qt5/QtCore/qobjectdefs.h:47:0,
from /usr/include/qt5/QtCore/qobject.h:48,
from /usr/include/qt5/QtCore/qcoreapplication.h:48,
from /usr/include/qt5/QtWidgets/qapplication.h:45,
from /usr/include/qt5/QtWidgets/QApplication:1,
from main.cpp:1:
/usr/include/qt5/QtCore/qobjectdefs_impl.h: In instantiation of ‘struct QtPrivate::FunctorReturnType<const char*, QtPrivate::List<> >’:
/usr/include/qt5/QtCore/qobject.h:305:158: required from ‘static typename QtPrivate::QEnableIf<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == (-1)), QMetaObject::Connection>::Type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const QObject*, Func2, Qt::ConnectionType) [with Func1 = void (QAbstractButton::*)(bool); Func2 = const char*; typename QtPrivate::QEnableIf<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == (-1)), QMetaObject::Connection>::Type = QMetaObject::Connection; typename QtPrivate::FunctionPointer<Func>::Object = QAbstractButton]’
main.cpp:17:83: required from here
/usr/include/qt5/QtCore/qobjectdefs_impl.h:633:78: error: request for member ‘operator()’ in ‘QtPrivate::FunctorReturnType<Functor, QtPrivate::List<Tail ...> >::dummy<const char*>()’, which is of non-class type ‘const char*’
typedef decltype(dummy<Functor>().operator()((dummy<ArgList>())...)) Value;
Edit:
Yes, I know changing the signal syntax to the QT4 standard "SIGNAL(clicked(bool))" would fix it, but I'm trying to get away from that syntax, and more importantly, understand the problem.
回答1:
You're mixing the old syntax and the new. Pick one per call to connect/disconnect. For overloaded signals/slots you'll need to cast the function pointer to the proper type in case of the new syntax
回答2:
I searched on stackoverflow for this type of problem, but didn't find anything, until Silicomancer pointed me to quite an excellent post - Part/Rule 5.
After reading this, the solution was simple:
QObject::connect(rbtn_0, &QRadioButton::clicked, this, &front_end::rbtn_toggle);
来源:https://stackoverflow.com/questions/38818170/qt5-radio-button-signal-not-compatible-with-function-even-though-it-should-be