I wanted to create a class waiting for Signal so I could connect all the signals.
But the template function doesn't seem to know the type of signal.
I tried this code:
SignalWaiter.h
class SignalWaiter
{
private:
SignalWaiter();
public:
template <typename Func>
static std::unique_ptr<SignalWaiter> Connect(QObject* sender, Func signal);
public:
bool Wait(int milliseconds = 1000);
private:
QTimer m_timer;
QEventLoop m_loop;
};
template<typename Func>
inline std::unique_ptr<SignalWaiter> SignalWaiter::Connect(QObject* sender, Func signal)
{
std::unique_ptr<SignalWaiter> ptr(new SignalWaiter());
QObject::connect(sender, signal, &(ptr->m_loop), &QEventLoop::quit);
QObject::connect(&(ptr->m_timer), &QTimer::timeout, &(ptr->m_loop), &QEventLoop::quit);
return ptr;
}
SignalWaiter.cpp
SignalWaiter::SignalWaiter()
{
m_timer.setSingleShot(true);
}
bool SignalWaiter::Wait(int milliseconds)
{
m_timer.start(milliseconds);
m_loop.exec();
return m_timer.isActive();
}
I wrote the code like this, but I get a compilation error in the part I use:
warning C4834: discarding return value of function with 'nodiscard' attribute
error C2665: 'QObject::connect': none of the 4 overloads could convert all the argument types
message : could be 'QMetaObject::Connection QObject::connect(const QObject *,const char *,const char *,Qt::ConnectionType) const'
message : or 'QMetaObject::Connection QObject::connect(const QObject *,const QMetaMethod &,const QObject *,const QMetaMethod &,Qt::ConnectionType)'
message : or 'QMetaObject::Connection QObject::connect(const QObject *,const char *,const QObject *,const char *,Qt::ConnectionType)'
message : or 'QMetaObject::Connection QObject::connect<Func,void(__cdecl QEventLoop::* )(void)>(const QWebEngineView *,Func1,const QEventLoop *,Func2,Qt::ConnectionType)'
with
[
Func=void (__cdecl QWebEngineView::* )(bool),
Func1=void (__cdecl QWebEngineView::* )(bool),
Func2=void (__cdecl QEventLoop::* )(void)
]
message : while trying to match the argument list '(QObject *, Func, QEventLoop *, void (__cdecl QEventLoop::* )(void))'
with
[
Func=void (__cdecl QWebEngineView::* )(bool)
]
message : see reference to function template instantiation 'std::unique_ptr<SignalWaiter,std::default_delete<SignalWaiter>> SignalWaiter::Connect<void(__cdecl QWebEngineView::* )(bool)>(QObject *,Func)' being compiled
with
[
Func=void (__cdecl QWebEngineView::* )(bool)
]
Why is there such an error? Can't the template get the signal type?
note: I also tried template constructor (Because I thought Func would be deduced):
class SignalWaiter
{
public:
template <typename Func>
SignalWaiter(QObject* sender, Func signal);
public:
bool Wait(int milliseconds = 1000);
private:
QTimer m_timer;
QEventLoop m_loop;
};
template<typename Func>
inline SignalWaiter::SignalWaiter(QObject* sender, Func signal)
{
m_timer.setSingleShot(true);
QObject::connect(sender, signal, &m_loop, &QEventLoop::quit);
QObject::connect(&m_timer, &QTimer::timeout, &m_loop, &QEventLoop::quit);
}
inline bool SignalWaiter::Wait(int milliseconds)
{
m_timer.start(milliseconds);
m_loop.exec();
return m_timer.isActive();
}
I am sorry for my poor English.
If Func
isn't a QObject
member-function pointer, the connection can't be made. You need to deduce the source object type too:
template<typename Sender, typename Func>
static std::unique_ptr<SignalWaiter> Connect(Sender* sender, Func signal);