robot
robot

Reputation: 1

How process signals in an external thread

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

Answers (1)

Vladimir Bershov
Vladimir Bershov

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

Related Questions