1
votes

Is there anythin wrong with this, it's giving me weird compilation errors:

candidate function not viable: no known conversion from 'void (QThread::*)(QThread::QPrivateSignal)' to 'const char *' for 2nd argument

QTimer timer;
timer.setInterval(3000);
connect(&timer, &QTimer::timeout, this, &ThisClass::runConnectionCheck);
QThread connectionThread;
timer.moveToThread(&connectionThread);
connect(&connectionThread, &QThread::started, &timer, &QTimer::start);
connectionThread.start();
3

3 Answers

4
votes

There are 2 QTimer slots called start(), so the compiler has that confusion, so you should QOverload:

connect(&connectionThread, &QThread::started, &timer, QOverload<>::of(&QTimer::start));

Or static_cast<>():

connect(&connectionThread, &QThread::started, &timer,static_cast<void (QTimer::*)()>(&QTimer::start));

@KubaOber provides 2 options:

C++14:

qOverload<>(&QTimer::start)

Lambda:

[&]{ timer.start(); }
1
votes

That you face this problem to begin with is the result of a complication you've added: the connection is not necessary at all. You can start the timer right away and then move it. The timer won't fire until the control returns to the event loop in the thread where the timer is, and that doesn't happen in your code since the timer is moved to another thread before your code returns to the event loop (if any) that this code runs on.

This code does the job just as well:

// https://github.com/KubaO/stackoverflown/tree/master/questions/timer-move-start-53200294
#include <QtCore>
int main(int argc, char *argv[]) {
   QCoreApplication app(argc, argv);
   int fired = 0;

   QTimer timer;
   QThread connectionThread;
   QObject::connect(&timer, &QTimer::timeout, [&] {
      Q_ASSERT(QThread::currentThread() == &connectionThread);
      ++fired;
      timer.moveToThread(qApp->thread());  // move the timer back to allow destruction
      QCoreApplication::quit();
   });
   timer.start(3000);
   timer.moveToThread(&connectionThread);

   Q_ASSERT(!fired);
   connectionThread.start();
   app.exec();
   Q_ASSERT(fired);

   connectionThread.quit();
   connectionThread.wait();
}
0
votes
connect(&connectionThread, &QThread::started, &timer, &QTimer::start);

Because QTimer::start has two overloaded function. You must use the old convention to point out which one to use.

connect(&connectionThread,SIGNAL(started()),&timer,SLOT(start()));