0

I have a thread created by inheriting QThread in which I called exec() to initiate the event loop. And this class that inherits QThread has a method in it.

How can I call that method from the main thread for it to execute in the child thread? I assume that the execution of that method has to be queued in the child thread's event loop, so calling threadObject->childThreadMethod() won't be a good idea. Is there any solution to this?

Jacob Krieg
  • 2,834
  • 15
  • 68
  • 140

2 Answers2

1

You can not call every member functions of the thread, but only slots and Q_INVOKABLE methods.

Use QMetaObject::invokeMethod() to call such a method, and make sure to set the connection type to Qt::QueuedConnection.

That way, the method will be called in the second thread whenever the control returns to the event loop in the second thread. The caller, i.e. the main thread, will continue immediately, so you won't be able to get a return value from the called method.

Behind the scenes, QMetaObject::invokeMethod adds a MetaCallEvent to the second thread's event queue.

Alternatively, create a signal/slot connection, and then emit a signal whenever you want the slot to be called in the other thread.

Thomas McGuire
  • 5,308
  • 26
  • 45
  • Thanks a lot for this very useful answer! What could happen if I set the connection type to `Qt::QueuedConnection`? Doesn't Qt figure out that the slot is in another thread to queue it itself? – Jacob Krieg Jun 27 '13 at 20:15
  • 1
    For signal/slot connections, Qt checks if the sender and receiver live in different threads, and if so, it uses a queued connection automatically. Not sure if this is also the case for QMetaObject::invokeMethod(), though. – Thomas McGuire Jun 27 '13 at 20:17
0

to run some function in a separate thread you can use QtConcurrent::run (i use it with QFutureWatcher). To run it every 5 or so seconds, use QElapsedTimer class

QFuture<void> future = QtConcurrent::run(this, &MyClass::foo2, ...foo2 arguments);

http://qt-project.org/doc/qt-4.8/qtconcurrentrun.html#run or check it here https://stackoverflow.com/search?q=QtConcurrent%3A%3Arun

or you can subclass QThread, reimplement QThread::run() method with the stuff you want to happen in your thread, and then create an instance of your thread and call start() on it.

Community
  • 1
  • 1
Shf
  • 3,463
  • 2
  • 26
  • 42
  • Thanks a lot for the answer! Using `QtConcurrent` is definitely a good idea but in this case I'm pretty forced in sticking wit `QThread` for some reasons. I did subclass `QThread` and reimplemented `run()` but what I want is to trigger an action in this child thread form within main thread. So I executed the child thread's event loop with `exec()` and I wish to trigger an execution of a method from within the main thread in the child thread. How can I 'trigger' the execution of this method situated in the child thread, as member of the class implementing `QThread`? – Jacob Krieg Jun 27 '13 at 20:00