0

Is there a way to pass a static method's argument to a class method?
I've tried with QTimer this way:

QTimer g_timer;
QString g_arg;

void staticMethod(QString arg)
{
  g_arg = arg;
  g_timer.start(1); // It will expire after 1 millisecond and call timeout()
}

MyClass::MyClass()
{
  connect(&g_timer, &QTimer::timeout, this, &MyClass::onTimerTimeout);

  this->moveToThread(&m_thread);
  m_thread.start();
}

MyClass::onTimerTimeout()
{
  emit argChanged(g_arg);
}

But I've got errors with threads because the staticMethod is called from a Java Activity, so the thread is not a QThread.

The errors are:

QObject::startTimer: QTimer can only be used with threads started with QThread

if g_timer is not a pointer, or

QObject::startTimer: timers cannot be started from another thread

if g_timer is a pointer and I instantiate it in MyClass constructor

Any suggestion? Thank you

Fausto01
  • 171
  • 14
  • there is no class method with arguments in the code. What errors do you get? – 463035818_is_not_an_ai Oct 04 '21 at 10:27
  • 1
    Problem is caused by fact that you are using `QTimer` as a global variable. This is constructed before `QApplication` so `QTImer` do not see default event loop. – Marek R Oct 04 '21 at 11:28
  • Also this line `this->moveToThread(&m_thread);` is very suspicious (there is not enogth context to say if it breaks anything). – Marek R Oct 04 '21 at 11:31

1 Answers1

3

In this specific instance you can use QMetaObject::invokeMethod to send the message over a cross-thread QueuedConnection:

QMetaObject::invokeMethod(&g_timer, "start", Qt::QueuedConnection, Q_ARG(int, 1));

This will deliver an event to the owning thread from where the start method will be called, instead of the current (non-QT) thread.

Botje
  • 26,269
  • 3
  • 31
  • 41