Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [Solved][Qt concurrent] Emit signal from run method do not work
Forum Updated to NodeBB v4.3 + New Features

[Solved][Qt concurrent] Emit signal from run method do not work

Scheduled Pinned Locked Moved General and Desktop
7 Posts 3 Posters 20.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V Offline
    V Offline
    vishwajeet
    wrote on last edited by
    #1

    Hi Guys,

    I have test() function which is executed using QtConcurrent::run method in different thread. My main thread is GUI thread. When any signal is emmited from test() function, main thread does not catch that so i tried to execute slot OnTestSignal() which executes in main thread and emit signal from there. still the signal is not emmited.

    @#include "mainwindow.h"
    #include "ui_mainwindow.h"

    #include <QtConcurrentRun>
    #include <QCoreApplication>
    #include <QTimer>

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    // Run test in different thread
    

    QtConcurrent::run((*this),&MainWindow::test);

    QObject::connect(this,SIGNAL(testSignal(int)),ui->progressBar,SLOT(setValue(int)),Qt::QueuedConnection);
    
    /**
      * This signal is emmited and progress bar changes
      */
    emit testSignal(qrand()0);
    

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }

    void MainWindow::test()
    {
    qDebug() << "start :" << QThread::currentThread() ->signalsBlocked()<< " : " << thread()->signalsBlocked();
    qDebug() << "Thread : " << QThread::currentThread() << " : " << thread();

    int i;
    int j;
    while(1) {
        ++i;
    
        if(i > 10) {
            i =0;
            QMetaObject::invokeMethod(this,"onTestSignal",Qt::QueuedConnection);
            //emit testSignal(); /* DOES NOT WORK */
    
        }
    }
    

    }

    void MainWindow::onTestSignal()
    {
    // Verify that test executed in different thread and this funtion is executed in main thread

    qDebug() << "onTestSignal() : " << QThread::currentThread() << " :Main Thread : " << thread();
    
    /**
      * Executed in main thread still signal is not been emmited, WHY ????
      */
    emit testSignal(qrand()0);
    
    // Did not work
    QCoreApplication::processEvents();
    

    }
    @

    What am i doing wrong here ? i should be getting a signal but that not happening

    Born To Code !!!

    1 Reply Last reply
    0
    • P Offline
      P Offline
      p-himik
      wrote on last edited by
      #2

      As i understand QMetaObject::invokeMethod() doesn't work either.
      Slot connected to a signal with Qt::QueuedConnection is invoked only when execution goes back to an event loop. And your while(1) construction prevents event loop from being entered. That is, events for onTestSignal are just queued without possibility for execution.

      1 Reply Last reply
      0
      • V Offline
        V Offline
        vishwajeet
        wrote on last edited by
        #3

        QMetaObject::InvokeMethod() method works here, and onTestSignal() function is also get called (Which executed in main thread ). it also prints the thread information. However it does not emit signal.

        Born To Code !!!

        1 Reply Last reply
        0
        • L Offline
          L Offline
          lgeyer
          wrote on last edited by
          #4

          Does connect(...) succeed? emit testSignal() should emit at least one int parameter.

          In addition, you should connect() before running your method. If your thread gets scheduled immediately you will miss all signals emitted before execution returns to your main thread.

          [quote author="p-himik" date="1322111612"]As i understand QMetaObject::invokeMethod() doesn't work either. Slot connected to a signal with Qt::QueuedConnection is invoked only when execution goes back to an event loop. And your while(1) construction prevents event loop from being entered. That is, events for onTestSignal are just queued without possibility for execution.[/quote]

          You'll need a running event loop in the receiving thread, which is not the one executing while(1).

          1 Reply Last reply
          0
          • V Offline
            V Offline
            vishwajeet
            wrote on last edited by
            #5

            For this example it is fine to miss few signals.

            Could you please suggest, how to run even loop in the above example ?

            Born To Code !!!

            1 Reply Last reply
            0
            • V Offline
              V Offline
              vishwajeet
              wrote on last edited by
              #6

              I understood what i was doing wrong here.

              For same issues please refer

              "http://developer.qt.nokia.com/wiki/ThreadsEventsQObjects":http://developer.qt.nokia.com/wiki/ThreadsEventsQObjects

              Born To Code !!!

              1 Reply Last reply
              0
              • L Offline
                L Offline
                lgeyer
                wrote on last edited by
                #7

                An event loop is started by calling exec(), for example QCoreApplication::exec(). Pending events can be processed (once) using processEvents().

                @
                class SignalTest : public QObject
                {
                Q_OBJECT

                public:
                void test()
                {
                qDebug() << Q_FUNC_INFO << QThread::currentThread() << thread();

                    emit signal(0);
                }
                

                signals:
                void signal(int parameter);

                public slots:
                void slot(int parameter)
                {
                Q_UNUSED(parameter);

                    qDebug() << Q_FUNC_INFO << QThread::currentThread() << thread();
                }
                

                };

                int main(int argc, char *argv[])
                {
                QCoreApplication application(argc, argv);

                qDebug() << Q_FUNC_INFO << QThread::currentThread();
                
                SignalTest signalTest;
                
                signalTest.connect(&signalTest, SIGNAL(signal(int)), &signalTest, SLOT(slot(int)), Qt::QueuedConnection);
                QtConcurrent::run(&signalTest, &SignalTest::test);
                
                return application.exec&#40;&#41;; // run event loop for main thread
                

                }
                @

                [quote author="vishwajeet" date="1322117812"]For this example it is fine to miss few signals.[/quote]

                Just make sure you are aware of it. Another pitfall is the following restriction of QtConcurrent::run():
                [quote]Note that the QFuture returned by QtConcurrent::run() does not support canceling, pausing, or progress reporting. The QFuture returned can only be used to query for the running/finished status and the return value of the function.[/quote]
                This means, that if your method never returns (as in your case, while(1) { ... }) you will have to provide a mechanism to break, otherwise you won't be able to terminate the thread.

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved