Results 1 to 8 of 8

Thread: Adding new Widgets in a seperate thread

  1. #1
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Adding new Widgets in a seperate thread

    Hi!

    I'm meaning to grab some data from a network connection, wrap the data into a QFrame and add those QFrames to my gui. The data comes slow, so it has to be a seperate process that doesn't block the gui. Also the user needs to have the possibility to stop the process in the middle. So what I did is this:

    Qt Code:
    1. class FrameGrabber : QThread;
    2.  
    3. void GUI::on_startGrabButton_clicked()
    4. {
    5. // Start the grabber thread.
    6. frameGrabber.start();
    7. }
    To copy to clipboard, switch view to plain text mode 

    And inside the frameGrabber thread:

    Qt Code:
    1. class MyFrame : QFrame;
    2.  
    3. void FrameGrabber::run()
    4. {
    5. int framesToGrab =1000;
    6.  
    7. while(framesToGrab >= 0)
    8. {
    9. MyFrame* f = NetworkConnection::grabFrame();
    10. GUI->addFrame(f);
    11. framesToGrab--;
    12. msleep(10);
    13. }
    14.  
    15. GUI->grabbingProcessFinished();
    16. }
    To copy to clipboard, switch view to plain text mode 

    The NetworkConnection class will instantiate a MyFrame, which is derived from QFrame. However, since the NetworkConnection doesn't know anything about the GUI, it cannot pass QWidget* parent as an argument to the constructor, so it can't instantiate a full blown QFrame yet. Only when MyFrame is added to the GUI with GUI->addFrame(), I try to set the parent with the setParent() method:

    Qt Code:
    1. void GUI::addFrame(MyFrame* f)
    2. {
    3. f->setParent(ui.GrabbedFrameBufferArea);
    4. }
    To copy to clipboard, switch view to plain text mode 

    This was the plan anyhow, but it doesn't work. I get a lot of this:

    QPixmap: It is not safe to use pixmaps outside the GUI thread
    QObject::setParent: Cannot set parent, new parent is in a different thread
    I don't quite get why it complains about a different thread adding Widgets to the gui. But in any case, what would be the right solution?

    Thanks
    Cruz

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Adding new Widgets in a seperate thread

    Use QImage in a worker thread, deliver it to the main GUI thread by using signals and slots, and create the frame in the GUI thread. You cannot use QPixmap or any widgets in worker threads.
    J-P Nurmi

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

    Cruz (16th January 2009)

  4. #3
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Adding new Widgets in a seperate thread

    Yes, good solution thaks!

  5. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Adding new Widgets in a seperate thread

    Also consider the option of doing it all in a single thread. You don't need a separate thread just to receive data over network.

  6. #5
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Adding new Widgets in a seperate thread

    And how can I accomplish that? The data transfer is triggered by a button. So first thing that happens is that a signal (clicked()) is sent into a slot. Coming from Java Swing I was raised to return an event handler as quickly as possible, otherwise I will keep the gui thread busy and the gui itself will freeze. So this is why I decided to start a thread from there and to return the slot as quickly as possible. So unless Qt itself takes care of splitting out a thread to handle the slot, so that the gui is not blocked by my sluggish program, I don't see how I can solve it without a thread.

  7. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Adding new Widgets in a seperate thread

    Longer explanation is here:
    http://doc.trolltech.com/qq/qq27-responsive-guis.html

    In short, network transfer is asynchronous - you schedule some request and then return from the function and Qt will notify you using a signal that the data is ready. You can then process it (read it to a buffer or process immediately) and return from the function. When more data arrives, you will be notified again. In the meantime the application can do other things (like refresh the user interface or make coffee).

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

    Cruz (16th January 2009)

  9. #7
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Adding new Widgets in a seperate thread

    I see where you are coming from. Well, actually it's not really a network connection, it's a more complicated custom USB communication with a robot. I simplified that detail in my question. It means that I can't take advantage of the solid network com solutions that Qt offers. And with that being gone, I personally think that the worker thread is the most elegant solution from all the alternatives proposed on that page.

  10. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Adding new Widgets in a seperate thread

    Quote Originally Posted by Cruz View Post
    I see where you are coming from. Well, actually it's not really a network connection, it's a more complicated custom USB communication with a robot.
    That doesn't change anything. It's a remote data source, that's all that counts.

    It means that I can't take advantage of the solid network com solutions that Qt offers.
    Sure you can. You can read from USB in an asynchronous way, you can even use QExtSerialPort probably and there are always timers. Threads are really not required here.

    And with that being gone, I personally think that the worker thread is the most elegant solution from all the alternatives proposed on that page.
    Well... Java itself is said to be elegant and that probably ends its advantages over other languages. Doing everything in threads is a nice separation of code but it is often crude when it comes to communication with other components and it adds some overhead to the application. Using signals and slots and event-driven flow gives you the same separation without the down sides. Sure, it might look hard at first but once you grasp it, it becomes very natural.

Similar Threads

  1. Starting QT GUI in a seperate Thread
    By bbui210 in forum Qt Programming
    Replies: 8
    Last Post: 27th June 2018, 16:17
  2. Replies: 4
    Last Post: 2nd December 2008, 04:19
  3. KDE/QWT doubt on debian sarge
    By hildebrand in forum KDE Forum
    Replies: 13
    Last Post: 25th April 2007, 06:13
  4. Replies: 10
    Last Post: 20th March 2007, 22:19
  5. Replies: 11
    Last Post: 7th July 2006, 13:09

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.