Results 1 to 9 of 9

Thread: QThread and signals

  1. #1
    Join Date
    Jan 2007
    Location
    Paris
    Posts
    459
    Thanks
    98
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt5

    Default QThread and signals

    Hey there,

    I'm using two threads : one for my GUI, one for my network library.
    Here is my network library run function:

    Qt Code:
    1. /* virtual */ void ZePurpleApi::run()
    2. {
    3. (...)
    4.  
    5. GMainLoop *loop = g_main_loop_new(NULL, FALSE);
    6. g_main_loop_run(loop);
    7.  
    8. // Qt never gets there
    9.  
    10. exec();
    11. }
    To copy to clipboard, switch view to plain text mode 

    - The library I'm using requires : g_main_loop_run(loop);
    - Between my two threads I'm communicating using signals.
    - I need to call exec() to receive signal from my GUI main thread.

    Is it possible to exec the thread and then start the g_main_loop_run(loop); ?

    Thanks.
    Last edited by bunjee; 27th March 2008 at 01:08.

  2. #2
    Join Date
    Mar 2008
    Posts
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread and signals

    Could you time share the two event loops? Something like this:

    Qt Code:
    1. bool run = true;
    2. while(run)
    3. {
    4. QEventLoop eventLoop;
    5. GMainLoop *loop = g_main_loop_new(NULL, FALSE);
    6.  
    7. eventLoop.processEvents(AllEvents, 100ms);
    8.  
    9. g_main_context_prepare();
    10. g_main_context_query();
    11. g_main_context_check();
    12. g_main_context_dispatch();
    13. }
    To copy to clipboard, switch view to plain text mode 

    Simulating running both the event loops in a single thread.

  3. #3
    Join Date
    Jan 2007
    Location
    Paris
    Posts
    459
    Thanks
    98
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt5

    Default Re: QThread and signals

    Hmm,

    This looks like a "hack" is there a more proper way to do it ?

  4. #4
    Join Date
    Jan 2007
    Location
    Paris
    Posts
    459
    Thanks
    98
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt5

    Default Re: QThread and signals

    This is how I'm currently doing :

    My Thread run function:

    Qt Code:
    1. /* virtual */ void ZePurpleApi::run()
    2. {
    3. // Starting event loop
    4. exec();
    5. }
    To copy to clipboard, switch view to plain text mode 

    The slot I'm calling right after thread->start:

    Qt Code:
    1. void ZePurpleApi::onThreadStart()
    2. {
    3. // We are in the good thread here
    4. g_print("ZePurpleApi - onThreadStart %d\n", currentThreadId());
    5.  
    6. InitPurpleApi();
    7.  
    8. GMainLoop *loop = g_main_loop_new(NULL, FALSE);
    9.  
    10. // Unfortunately the g_main_loop appears to block the Qt event loop
    11. g_main_loop_run(loop);
    12. }
    To copy to clipboard, switch view to plain text mode 

    I think I cannot adopt your approach sincie I need my init Before the g_main_loop_run(loop); and after the exec(); otherwise my lib signals aren't propagated correctly in the proper thread.

    Anybody has an idea?

  5. #5
    Join Date
    Jan 2007
    Location
    Paris
    Posts
    459
    Thanks
    98
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt5

    Default Re: QThread and signals

    I think I figured out what's wrong, I'll keep you posted.

  6. #6
    Join Date
    Mar 2008
    Posts
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread and signals

    Yeah, I agree its a hack.

    What I discovered, and what may be of help, is that the exec() call on QThread essentially creates a QEventLoop and calls exec() on it.

    So, you can create the event loop yourself.

    The interesting thing (at least for me) was that if I created the event loop myself it would 'catch' signals before disappearing into event(). Also, you can signal to another thread that this threads event loop is ready and will receive events.

    Qt Code:
    1. run()
    2. {
    3. QEventLoop eventLoop;
    4. emit eventLoopInited();
    5. eventLoop.exec();
    6. }
    7.  
    8. onThreadDoSomething()
    9. {
    10. // Do some work here...
    11. }
    To copy to clipboard, switch view to plain text mode 

    In another thread:
    Qt Code:
    1. onEventLoopInitied()
    2. {
    3. emit threadDoSomthing();
    4. }
    To copy to clipboard, switch view to plain text mode 

    The event loop will receive and queue events it receives between its constructor and the call to exec(). Obviously, it doesn't process them untill exec(), but this solved my problem.

    Anyway, best of luck. Please share your solution. I'd like to know how you manage to get to concurrent event loops playing nicely.
    Last edited by gabe; 27th March 2008 at 13:31.

  7. #7
    Join Date
    Jan 2007
    Location
    Paris
    Posts
    459
    Thanks
    98
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt5

    Default Re: QThread and signals

    Hey there,

    I'm back after some refining of my thread.
    here it is:

    Qt Code:
    1. void ZePurpleThread::run()
    2. {
    3. g_print("PIKAAAAAABOOOOOOOOOOOOOO\n");
    4. mPurpleApi = new ZePurpleApi();
    5. mServiceApi = mPurpleApi;
    6. mPurpleApi->Init();
    7.  
    8. GMainLoop *loop = g_main_loop_new(NULL, FALSE);
    9. g_main_loop_run(loop);
    10. exec();
    11. }
    To copy to clipboard, switch view to plain text mode 
    I just can't get working those two loops together.
    I tried several solutions, here is what I did :

    - Run the thread.
    - Create my object.
    - Start object loop.
    - Run Exec.
    => Doesn't work
    - Run the thread.
    - Create my object.
    - Run Exec.
    - Start object loop.
    => Doesn't work
    - Run the thread.
    - Create my object.
    - Run Exec.
    - Catch the "started()" signal.
    - Emit a signal to start the object loop in its own thread
    => Doesn't work
    That's not possible to get g_main_loop_run() and exec() work altogether in a thread.
    So we need to find a non blocking solution either for exec() or g_main_loop_run().

    Has somebody ever coded this ?

  8. #8
    Join Date
    Jan 2007
    Location
    Paris
    Posts
    459
    Thanks
    98
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt5

    Default Re: QThread and signals

    Got it:
    Qt Code:
    1. void ZePurpleThread::run()
    2. {
    3. g_print("ZePurpleThread - run\n");
    4.  
    5. mPurpleApi = new ZePurpleApi();
    6. mServiceApi = mPurpleApi;
    7. mPurpleApi->Init();
    8.  
    9. g_timeout_add(100, ZePurpleThread::timerUpdate, NULL);
    10.  
    11. GMainLoop *loop = g_main_loop_new(NULL, FALSE);
    12. g_main_loop_run(loop);
    13. }
    14.  
    15. gboolean ZePurpleThread::timerUpdate(gpointer data)
    16. {
    17. //g_print("ZePurpleThread - timerUpdate\n");
    18. QEventLoop eventLoop;
    19. eventLoop.processEvents();
    20.  
    21. return true;
    22. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by bunjee; 27th March 2008 at 16:51.

  9. #9
    Join Date
    Jan 2008
    Posts
    27
    Thanks
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread and signals

    Is this the cleanest way? I literally just came to the forum since I am doing the same thing as you and it was the first thread on the list.

    I am currently doing this a really nasty hack and needed a new idea. In summary, it does the processing I need the thread to do (my network thread needs QTimer so events are needed), and then creates a timer that calls exit() 1 second later, and then runs exec(). I just hope exec() clears all the events in 1 second and then the exit() timer goes off and I am back.

    Here is my code:

    Qt Code:
    1. void NetThread::run()
    2. {
    3. NetMsg currentMsg;
    4.  
    5. while (1)
    6. {
    7. if (NetMsgQueue.isEmpty())
    8. {
    9. msleep(5);
    10. }
    11. else
    12. {
    13. /* Lock ? */
    14. #warning ADD MUTEX HERE
    15. currentMsg = NetMsgQueue.dequeue();
    16.  
    17. printf("Something in NetThread queue, processing it\n");
    18.  
    19. switch(currentMsg.type)
    20. {
    21. case NET_MSG_TYPE_SEND:
    22. printf("Send message found, processing it\n");
    23. writePkt(currentMsg.pPktDesc);
    24. break;
    25.  
    26. case NET_MSG_TYPE_RECEIVE:
    27. processPacket(currentMsg.pPktDesc);
    28. break;
    29. default:
    30. /* Unknown Msg Type */
    31. break;
    32. }
    33. }
    34.  
    35. QTimer *exitTimer = new QTimer();
    36. connect(exitTimer, SIGNAL(timeout()), this, SLOT(killEventLoop()));
    37. exitTimer->setSingleShot(true);
    38. #warning find good time value
    39. exitTimer->start(1000);
    40. exec();
    41. }
    42. }
    43.  
    44. void killEventLoop() { exit(); }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. QThread and QSlot
    By Xaar in forum Qt Programming
    Replies: 5
    Last Post: 6th December 2007, 21:37
  2. QThread and signals (linux/UNIX signals not Qt Signals)
    By Micawber in forum Qt Programming
    Replies: 1
    Last Post: 28th November 2007, 22:18
  3. Need some help about QProgressbar while using QThread
    By qzb1111 in forum Qt Programming
    Replies: 5
    Last Post: 31st July 2007, 14:52
  4. QThread exec proplem to stop...
    By patrik08 in forum Qt Programming
    Replies: 29
    Last Post: 21st May 2007, 07:51
  5. how to use QHttp inside QThread in Qt3
    By alusuel in forum Qt Programming
    Replies: 3
    Last Post: 14th July 2006, 11:19

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.