Results 1 to 7 of 7

Thread: QT4 style QThread and GUI communication

  1. #1
    Join Date
    May 2010
    Posts
    24
    Thanks
    14
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default QT4 style QThread and GUI communication

    I am using QT4 to develop an application that has two parts: a worker thread and a GUI. The threads job is to wait for data to be placed in a shared memory buffer. When data is available (indicated through the use of a blocking semaphore), the thread reads the data from the buffer, processes it, and needs to pass that data to the GUI for display.

    In QT4 the way of using the QThread class has changed. It is no longer recommended to subclass QThread (as it is an interface to the thread, and not the thread itself). Rather, examples show the creation of a class (based on QObject) that will actually run in the thread and perform the work.

    Given that… How do I communicate from the GUI to the thread? Do I (can I) post events from the GUI – and if so, do I post them to the instance of the QThread, or to the class I created that does the actual work inside the thread? I want the GUI to be able to tell the thread to stop its blocking operation and terminate (so that the application can close), but I cannot come up with a way to do that. Example code would be much appreciated!

    FYI: I had already created this application under QT3 using a subclassed QThread that polls the semaphore and posts an event to the GUI when data is ready. The GUI uses its customEvent() function to respond to the event, and a nonblocking message queue to communicate with the thread (inside its run function.) I’d like to do this differently, if possible, under QT4.

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QT4 style QThread and GUI communication

    You can still subclass QThread and reimplement run(), especially if you don't need an event loop in the thread.

    The "no longer recommended" bit comes from the observation that a lot of people had difficulties to understand that the QThread object itself belongs to the read that created it, not the thread executing its run() method. If one understands that (and does not try to put slots into the QThread subclass) then all is fine.

    Anyway, if you want to use the worker object technique you simply make signal/slot connections between the worker and objects in the main thread. Since the worker gets moved into the thread, any signal/slot connection between it and main thread objects will be handled as Qt::QueuedConnections.
    Basically very similar to your Qt3 custom event technique, but without needing any special code and working into both directions.

    Note however, that as long as the worker object blocks on the semaphore, its event processing is halted and slot calls for signals from main thread objects will be queued until event processing resumes.

    Cheers,
    _

  3. The following user says thank you to anda_skoa for this useful post:

    Ronayn (22nd February 2013)

  4. #3
    Join Date
    May 2010
    Posts
    24
    Thanks
    14
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: QT4 style QThread and GUI communication

    Quote Originally Posted by anda_skoa View Post
    You can still subclass QThread and reimplement run(), especially if you don't need an event loop in the thread.

    The "no longer recommended" bit comes from the observation that a lot of people had difficulties to understand that the QThread object itself belongs to the read that created it, not the thread executing its run() method. If one understands that (and does not try to put slots into the QThread subclass) then all is fine.

    Anyway, if you want to use the worker object technique you simply make signal/slot connections between the worker and objects in the main thread. Since the worker gets moved into the thread, any signal/slot connection between it and main thread objects will be handled as Qt::QueuedConnections.
    Basically very similar to your Qt3 custom event technique, but without needing any special code and working into both directions.

    Note however, that as long as the worker object blocks on the semaphore, its event processing is halted and slot calls for signals from main thread objects will be queued until event processing resumes.

    Cheers,
    _
    Thanks for that speedy and helpful reply.

    Do you have any suggestions about how to handle a worker object when its blocking on the semaphore? I suppose I could make it a non-blocking semaphore, and set up a timer event to check the semaphore. However, doing so would amount to polling in thread (which I thought was bad).

    Essentially, I need a worker to sit and wait for data -- but I also need a way to break that wait from outside the thread, in case the user closes the application.

  5. #4
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QT4 style QThread and GUI communication

    change the semaphore for a signal/slot. That way the worker will know when to grab the data, and it is also open to receive other signals.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

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

    Ronayn (25th February 2013)

  7. #5
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QT4 style QThread and GUI communication

    Quote Originally Posted by Ronayn View Post
    Essentially, I need a worker to sit and wait for data -- but I also need a way to break that wait from outside the thread, in case the user closes the application.
    If you need a way to terminate the thread at any given time then you basically cannot do a call that blocks for an unspecified time.
    QSystemSemaphore (assuming that is what you had in mind) is therefore out of the question, it relies on the other process calling release() reliably.

    What you could do instead is making the notification part ("hey, new data available") asynchronous, e.g. by using QLocalSocket/QLocalServer.

    You would still have a blocking section, i.e. while having locked() the QSharedMemory instance, but that should not be too long assuming the other process only keeps its end locked as long as necessary.

    Cheers,
    _

  8. The following user says thank you to anda_skoa for this useful post:

    Ronayn (25th February 2013)

  9. #6
    Join Date
    May 2010
    Posts
    24
    Thanks
    14
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: QT4 style QThread and GUI communication

    Thanks anda_skoa and amleto for your replies.

    Unfortunately, I am constrained by the nature of what I am with. My application waits for data to be placed in a shared memory buffer by another application (which I have no control over). When that other application has placed data in the shared memory, it performs a semaphore operation to notify anyone "listening" that there is new data available.

    I have to work with that

    Like I mentioned, I have worked this out before using polling and message queues, but I did not like my solution and was hoping there was a more simple/elegant way to do what I need.

  10. #7
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QT4 style QThread and GUI communication

    Many problems can be solved with enough levels of indirection. Consider adding another layer in between your semaphore app and your worker:

    Attach the semaphore to another qt thread. Let that thread (can be blocked by semaphore) communicate with the worker (non blocking)

    also let the gui communicate with the worker (signal/slot) to indicate cancelling.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

Similar Threads

  1. need help on inter Qthread communication
    By Ratheendrans in forum Qt Programming
    Replies: 2
    Last Post: 12th October 2010, 06:39
  2. QThread interthread communication
    By SABROG in forum Qt Programming
    Replies: 1
    Last Post: 15th June 2009, 19:57
  3. QThread interthread communication
    By hunsrus in forum Qt Programming
    Replies: 2
    Last Post: 10th March 2009, 15:49
  4. QThread communication with GUI
    By ldiamond in forum Qt Programming
    Replies: 1
    Last Post: 14th March 2008, 01:00
  5. Communication between QThread and Yes/No QMessageBox?
    By pmaktieh.sirhc in forum Qt Programming
    Replies: 11
    Last Post: 25th January 2007, 04:45

Tags for this Thread

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.