Results 1 to 8 of 8

Thread: QThread sends signal to main thread immediatly

  1. #1
    Join Date
    Aug 2010
    Posts
    16
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Windows

    Default QThread sends signal to main thread immediatly

    Is there a way that the signal a QThread sends to main thread is received immediately (and not queued)?
    I mean that if a thread signals then the main thread will receive it AFTER it has done its own work (using the thread-safe connection type QueuedConnection).

  2. #2
    Join Date
    Dec 2008
    Location
    Poland
    Posts
    383
    Thanks
    52
    Thanked 42 Times in 42 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: QThread sends signal to main thread immediatly

    Look into Qt:irectConnection, or enum Qt::ConnectionType.

  3. #3
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: QThread sends signal to main thread immediatly

    Quote Originally Posted by Talei View Post
    Look into Qt:irectConnection, or enum Qt::ConnectionType.
    Oh oh :-)
    That will not work ;-)

    If you use multiple threads, you have to use a queued connection.
    Last edited by tbscope; 27th August 2010 at 06:34.

  4. #4
    Join Date
    Dec 2008
    Location
    Poland
    Posts
    383
    Thanks
    52
    Thanked 42 Times in 42 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: QThread sends signal to main thread immediatly

    Quote Originally Posted by tbscope View Post
    Oh oh :-)
    That will not work ;-)

    If you use multiple threads, you have to use a queued connection.
    Is it really that funny? Or maybe I made some basic/noob mistake?
    I simply pointed out that there is a posibility of using DirectConnection and thread poster should check it out.

    About thread what about that connection configuration?
    Qt Code:
    1. connect( th, SIGNAL( started() ), thObj, SLOT(doJob()), Qt::QueuedConnection ); //start thObj
    2. connect( thObj, SIGNAL( finThObj( int ) ), this, SLOT(thJobFin(int)), Qt::DirectConnection ); //job done Direct ret
    3. connect( thObj, SIGNAL( thObjQuit() ), th, SLOT(quit()), Qt::QueuedConnection ); // queued quit
    4. connect( th, SIGNAL( finished() ), this, SLOT(thQuit()), Qt::QueuedConnection ); //clean up i.e. delete th and thObj
    To copy to clipboard, switch view to plain text mode 
    Everything, except finThObj(int), is queued. finThObj(), in my opinion (please correct me if I'm wrong), should return immediately after execution.

    And in thObj job I did this:

    Qt Code:
    1. void objThDirConn::doJob()
    2. {
    3. qDebug() << "thread job: in " << this->thread();
    4.  
    5. int k = 0;
    6. for( int i = 0; i < 1000000000; ++i)
    7. {
    8. k++;
    9. }
    10.  
    11. emit finThObj( k );
    12. emit thObjQuit();
    13. }
    To copy to clipboard, switch view to plain text mode 

    And if I use QList<QThread> and run i.e. 4 thread it still should work, or maybe I'm mistaken here?.

    Ofcourse my implementation don't work on the shared data.

    Full example code
    thDirConn.zip

  5. #5
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: QThread sends signal to main thread immediatly

    Quote Originally Posted by Talei View Post
    Is it really that funny? Or maybe I made some basic/noob mistake?
    I simply pointed out that there is a posibility of using DirectConnection and thread poster should check it out.
    Sorry, I never have the intention to insult someone.

    You can not use direct connections with multiple threads. Yes, it will work most of the time or sometimes. No, you will not be sure of the results.

    Be aware that using direct connections when the sender and receiver live in different threads is unsafe if an event loop is running in the receiver's thread, for the same reason that calling any function on an object living in another thread is unsafe.
    In other words, you send a signal in thread 1 while a slot in thread 2 is connected to it. You need to wait till the program gets to the event loop of thread 2 to handle the slot. If you use a direct connection, thread 2 will not be in its event loop, resulting in problems.

    All is fine when you have only one event loop. But with multiple event loops, you need to wait.
    Last edited by tbscope; 27th August 2010 at 08:27.

  6. The following user says thank you to tbscope for this useful post:

    Talei (27th August 2010)

  7. #6
    Join Date
    Aug 2010
    Posts
    16
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QThread sends signal to main thread immediatly

    Talei what about putting the "emit finThObj( k );" in the for-loop?

  8. #7
    Join Date
    Aug 2010
    Posts
    16
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QThread sends signal to main thread immediatly

    Here is my example:

    //MyThread.h file
    #include <QtGui>
    #include <iostream>


    class MyThread : public QThread
    {
    Q_OBJECT

    public:
    MyThread ();
    void run();

    signals:
    void Signal_AppendTextThread(QString);


    protected slots:
    void Slot_ShowMessage(QString);

    };


    //MyThread.cpp file
    #include "MyThread.h"


    MyThread::MyThread(): QThread()
    {
    }

    void MyThread:Slot_ShowMessage(const std::string &text)
    {
    }

    void MyThread::run()
    {

    for(int i=1;i<100;i++)
    {
    emit Signal_AppendTextThread("emitting thread signal ");
    }

    exec(); //do i really need this?
    }


    // MyMainWindow.h file

    #include <QtGui/QMainWindow>
    #include <QtGui/QApplication>
    #include <QtGui/QLineEdit>
    #include "MyThread.h"



    class MyMainWindow: public QMainWindow
    {
    Q_OBJECT

    public:
    MyMainWindow( QWidget * pParent = 0);
    ~MyMainWindow();

    MyThread m_pApplyAlgorithmThread;
    QTextEdit *m_pTextEdit;

    protected slots:
    void Slot_ShowMessage(QString);

    };



    //MyMainWindow.cpp file

    #include "MyMainWindow.h"

    MyMainWindow::MyMainWindow( QWidget * pParent) :
    QMainWindow( pParent )
    {

    setWindowTitle( "Thread Test" );

    m_pTextEdit = new QTextEdit(this);
    m_pTextEdit->setReadOnly(true);
    m_pTextEdit->setGeometry(0,0,200,200);


    m_pApplyAlgorithmThread.start();

    connect(&m_pApplyAlgorithmThread, SIGNAL(Signal_AppendTextThread(QString)),
    this, SLOT(Slot_ShowMessage(QString)),Qt::QueuedConnecti on );


    showMaximized();

    for(int i=1;i<100;i++)
    {
    m_pTextEdit->append("main");
    m_pTextEdit->repaint();

    }
    }

    MyMainWindow::~MyMainWindow()
    {
    }

    void MyMainWindow::Slot_ShowMessage(QString)
    {
    m_pTextEdit->append(text.c_str());
    m_pTextEdit->repaint();
    }


    It prints out
    main
    main
    .
    .
    .
    main //#100 th time
    emitting thread signal
    emitting thread signal
    .
    .
    .
    emitting thread signal //#100 th time

    I want the thread to emit the signal and the signal to be "executed" by main's slot immediately
    (*something* like this)
    main
    main
    .
    .
    .
    emitting thread signal //thread emitted signal and "executed" by main's slot
    emitting thread signal //thread emitted signal and "executed" by main's slot
    emitting thread signal //thread emitted signal and "executed" by main's slot
    emitting thread signal //thread emitted signal and "executed" by main's slot
    .
    .
    .
    emitting thread signal //thread emitted signal and "executed" by main's slot // unknown number of signal sent (as long as the thread had the CPU?)
    main
    .
    .
    .
    emitting thread signal //thread emitted signal and "executed" by main's slot
    .
    .
    .
    emitting thread signal //thread emitted signal and "executed" by main's slot // unknown number of signal sent (as long as the thread had the CPU?)
    main
    .
    .
    .

  9. #8
    Join Date
    Dec 2008
    Location
    Poland
    Posts
    383
    Thanks
    52
    Thanked 42 Times in 42 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: QThread sends signal to main thread immediatly

    Quote Originally Posted by BIllNo123 View Post
    Talei what about putting the "emit finThObj( k );" in the for-loop?
    With DirectConnection ..., it will CRASH See tbscope post for more details.
    With QueuedConnection it works fine.

    To clarify I never use DirectConnection, I sugested using it because I didn't know (You didn't post it) what exactly You want to achieve. And my reply to tbscope post was simply academic debate and learning opportunity .

    Your QThread subclass is "wrong". Please read this or simply download my example and see how I run code in thread. (don't forget to change connection type to queue ).
    Also You code in subclassed QThread is "wrong".
    Do something like this:

    Qt Code:
    1. void myThread::run()
    2. {
    3. QTimer::singleShot( 0, this, SLOT(heavyDutyJob()) );
    4. this->exec();
    5. }
    6.  
    7. void myThread::heavyDutyJob()
    8. {
    9. //do stuf here
    10. this->exit();
    11. }
    To copy to clipboard, switch view to plain text mode 

    And the code that I post above is wrong, because You shouldn't use QObject macro in QThread subclass. See the link.

    AFAIK manual/qtdocs don't says to subclass QThread ONLY on QTcpSocket class (and they use QTcpSocket as an example there), and that's because QTcpSocket lives in the object it was created in. So to use QTcpSocket in thread You need create it in thread. And the whole commotion around QThread itself is probably because of that.

    To sum it up do somethink like this:
    Qt Code:
    1. QObjec *myWorkingObject = new QObject();
    2. QThread *th = new QThread(); // or QThread th; whaever suits Your needs
    3. myWorkingObject.moveToThread(th);
    4. //.....
    5. connect(....)
    6. th->start();
    To copy to clipboard, switch view to plain text mode 

    and use siganl/slots as You want.

    And the reason Why You code output was wrong (well output is actually correct) is due to for-loop in MyMainWindow, because that will block Your program (until for loop < 100). And it is exactly what You see in output. 100 x "main" and "signal", 100 x "main" and "signal" ...
    Simply Your design is wrong.
    Last edited by Talei; 27th August 2010 at 11:40.

  10. The following user says thank you to Talei for this useful post:

    BIllNo123 (27th August 2010)

Similar Threads

  1. QThread Signal Not Received By Main Thread Slot
    By EF2008 in forum Qt Programming
    Replies: 7
    Last Post: 4th June 2010, 09:06
  2. Replies: 9
    Last Post: 28th November 2009, 21:31
  3. Replies: 16
    Last Post: 7th October 2009, 09:17
  4. Determine if QThread::currentThread is main thread?
    By chaoticbob in forum Qt Programming
    Replies: 2
    Last Post: 17th December 2008, 07:26
  5. Replies: 1
    Last Post: 11th September 2008, 21:45

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.