Reputation: 1
A external component has a callback which executes in its internal thread start with std::thread, I want to create a qt component(not UI) in this thread, connect other qt components signal to this qt component, and let the slot function execute in this internal thread. I expect to execute to run the event loop once callback triggerd to process pending slot functions invoking.
// call in a thread start with std::thread in ExternalComponent, this method invoke periodically.
void ExternalComponent::InternalProcessing() {
//do other thing...
//invoke callback
callback();
}
void CustomQtComponent::Init() {
externalComponent.SetCallback([]() {
// first time, create a Worker
if (worker_ == nullptr) {
worker_ = new Worker();
}
// process pending signals(invoke worker_ slot methods) in this thread
// ...
// do other things.
});
}
// call by ui thread
void CustomQtComponent::DoSomething() {
// do xxxx
// ...
// emit a signal, to let something process in callback threads
// emit cutstomSignalWhichConnectToWokerSlots();
}
Because external threads not start by QThread, so though we can get the QThread object in its thread(in callback), but it has no event loop. Could I construct a QEventLoop in callback thread, and let it receive and process signals sending to worker_?
Upvotes: 0
Views: 218
Reputation: 2832
Working example with trivial classes:
...{
std::thread([this]()
{
qDebug() << "current thread is" << QThread::currentThread();
auto recv = new Worker;
connect(this, &MainWin::call, recv, &Worker::callMe);
/* Note that recv's slots will be called in the thread where
the recv object lives */
QEventLoop eventLoop;
// Do not forget to setup exit mechanism
connect(qApp, &QApplication::aboutToQuit,
&eventLoop, &QEventLoop::quit);
// Do not forget to start the loop but only after connections
eventLoop.exec();
}).detach();
// After start the thread we can trigger the signal
QThread::msleep(1000); // make sure won't be called earlier than connect()
// Check the threads are different
qDebug() << "current thread is" << QThread::currentThread();
emit call();
}
Where
void Worker::callMe()
{
qDebug() << "callMe invoked";
qDebug() << "current thread is" << QThread::currentThread();
}
See also the list of useful links about objects, signals-slots and threading in Qt, in the answer: https://stackoverflow.com/a/60755238/4149835
Upvotes: 0