Results 1 to 7 of 7

Thread: Showing progress bar while worker thread works

  1. #1
    Join Date
    Feb 2009
    Posts
    79
    Thanks
    11
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Showing progress bar while worker thread works

    Hi guys!

    I've got the following situation:

    Somewhere in my GUI I start a lengthy computation in my BackgroundImageItem which inherits from QThread:

    Qt Code:
    1. BackgroundImageItem* back = new BackgroundImageItem(filename);
    2. // let the worker thread work:
    3. back->start();
    To copy to clipboard, switch view to plain text mode 

    to inform the user that the application is working, I have written the following simple self-updating Progressbar:

    Qt Code:
    1. class ThreadedProgressBar : public QThread, public QProgressBar
    2. {
    3. public:
    4. ThreadedProgressBar(QWidget * parent)
    5. : QProgressBar(parent)
    6. {
    7. this->setGeometry(
    8. (parent->width() - 300)/2,
    9. (parent->height()-30)/2,
    10. 300, 30);
    11. this->setTerminationEnabled(true);
    12. this->start();
    13. };
    14. void run()
    15. {
    16. while(true)
    17. {
    18. this->setValue((this->value()+20)%100);
    19. this->update();
    20. this->msleep(100);
    21. }
    22. };
    23. virtual ~ThreadedProgressBar();
    24. };
    To copy to clipboard, switch view to plain text mode 

    What I did then to show this ThreadedProgressbar was:

    Qt Code:
    1. BackgroundImageItem* back = new BackgroundImageItem(filename);
    2. // let the worker thread work:
    3. back->start();
    4. //start the progressBar,
    5. //note: this->parentWidget() is the main widget of my app
    6. ThreadedProgressBar * pbar = new ThreadedProgressBar(this->parentWidget());
    7. // Join the gui thread with the worker thread
    8. back->wait();
    9. // a thread must be terminated before being deleted
    10. pbar->terminate();
    11. //clean up
    12. delete pbar;
    To copy to clipboard, switch view to plain text mode 


    BUT THE PROGRESS BAR DOES NOT SHOW UP !!!!

    I'm sure I just did a small mistake!

    Thanks for zour help in advance,
    best regards,
    Olli

  2. #2
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Showing progress bar while worker thread works

    i) you must not use widgets in any but the gui (aka main) thread
    ii) assuming you did not inherit QThread and QProgressBar:
    when you put your ThreadedProgressBar to sleep, no events will get progressed

    possible solutions:
    i) use a QTimer to regularly update a QProgressBar
    ii) have your worker thread signal its progress and connect that to some gui slot
    iii) use a QProgressBar and put it into "busy mode" by setting min=max=0 to indicate that your program is doing something

    HTH

  3. #3
    Join Date
    Jan 2009
    Posts
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Showing progress bar while worker thread works

    The gui may only be controlled by the main thread for portability reasons. Windows WILL behave strangely or even crash if you do otherwise.

  4. #4
    Join Date
    Jan 2008
    Location
    Poland
    Posts
    687
    Thanks
    4
    Thanked 140 Times in 132 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Showing progress bar while worker thread works

    same on X11 - crash for sure :] better look if some of the QtConcurrent functionality can be useful for you. QtConcurrent provides for example something like QFutureWatcher whic can give you the progress of task, when you use QtConcurrent for heavy computations.
    I would like to be a "Guru"

    Useful hints (try them before asking):
    1. Use Qt Assistant
    2. Search the forum

    If you haven't found solution yet then create new topic with smart question.

  5. #5
    Join Date
    Feb 2009
    Posts
    79
    Thanks
    11
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Showing progress bar while worker thread works

    Hi!

    Thanks for your replies.

    But my Problem is still not solved.

    I have changed my strategy a bit:
    I am extensively working on a QGraphicsView and Scene, so the idea is to hide all QGraphicsItems in my scene once the computation starts, and to show a Progressbar which is a subclass of QGraphicsItem.

    the code looks like that:
    Qt Code:
    1. //MainView is derived from QGraphicsView
    2. void MainView::loadBackgroundImage(const QString& filename)
    3. {
    4. // the background item shall always be newly created.
    5. if(this->scene()->items().contains(this->m_background))
    6. this->scene()->removeItem(this->m_background);
    7. delete m_background;
    8.  
    9. //hide all scene items
    10. this->m_scalable_item->setVisible(false);
    11.  
    12. //get the progressbar (derived from QGraphicsItem)
    13. GraphicsProgressBar * g = new GraphicsProgressBar;
    14. this->scene()->addItem(g);
    15. g->setPos(this->sceneRect().center());
    16.  
    17. this->scene()->update();
    18.  
    19. QTimer * timer = new QTimer(this);
    20. connect(timer, SIGNAL(timeout()), g, SLOT(updateProgress()));
    21. timer->start(100);
    22.  
    23. //BackgroundImageItem is derived from QObject, QThread and QGraphicsItem
    24. // start() starts the computation is background-thread
    25. m_background = new BackgroundImageItem(filename);
    26. m_background->start();
    27. qDebug() << "work started";
    28. //the gui thread should wait here until the worker has finished
    29. m_background->wait();
    30. qDebug() << QThread::currentThreadId() << "Waiting done.";
    31.  
    32. // I just add the background item here
    33. this->scene()->addItem(this->m_background);
    34. if(!this->scene()->items().contains(m_scalable_item))
    35. this->scene()->addItem(m_scalable_item);
    36. this->m_scalable_item->setVisible(true);
    37.  
    38. //free all timer resoureces and the progressbar
    39. timer->stop();
    40. timer->disconnect();
    41. g->disconnect();
    42. this->scene()->removeItem(g);
    43. delete g;
    44. delete timer;
    45. }
    To copy to clipboard, switch view to plain text mode 
    The Progressbar code looks like:
    Qt Code:
    1. class GraphicsProgressBar : public QObject, public QGraphicsItem
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6.  
    7. GraphicsProgressBar()
    8. {
    9. setZValue(5);
    10. status = 1;
    11. };
    12.  
    13. inline QRectF boundingRect() const { return QRectF(-66,-21,132,42); };
    14.  
    15. void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    16. {
    17. qDebug() << "paint";
    18. painter->drawRect(-66,-21,132,42);
    19. if(status >=1)
    20. painter->drawRect(-65,-20,40,40);
    21. if(status >=2)
    22. painter->drawRect(-20,-20,40,40);
    23. if(status >=3)
    24. painter->drawRect(25,-20,40,40);
    25. };
    26.  
    27. public slots:
    28.  
    29. void updateProgress()
    30. {
    31. status = (status+1)%4;
    32. qDebug() << QThread::currentThreadId() << status;
    33. //this->update();
    34. };
    35.  
    36.  
    37. private:
    38. int status;
    39. };
    To copy to clipboard, switch view to plain text mode 
    The progressbar does not show up.
    Also, the hiding
    The paint method gets never called!
    Also the debugmsg from updateProgress never appears.
    It seems that nothing I try to change at the graphicsScene or view has an effect.
    Its not even possible to hide all elements.

    HELP appreciated!

  6. #6
    Join Date
    Dec 2008
    Location
    France
    Posts
    93
    Thanked 23 Times in 22 Posts
    Qt products
    Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android

    Default Re: Showing progress bar while worker thread works

    Hi,

    I think your problem comes from following line :
    Qt Code:
    1. //the gui thread should wait here until the worker has finished
    2. m_background->wait();
    To copy to clipboard, switch view to plain text mode 

    It seems you want block the Gui thread during the processing. But how your progressbar should be managed and refreshed if the GUI thread is blocked ??

    You don't have to block the GUI thread, use QThread::finished() signal for manage post-treatement & cleaning once the processing is completed.

    'hope it will help you.

  7. The following user says thank you to nix for this useful post:

    olidem (27th April 2009)

  8. #7
    Join Date
    Feb 2009
    Posts
    79
    Thanks
    11
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Showing progress bar while worker thread works

    Quote Originally Posted by nix View Post
    Hi,

    I think your problem comes from following line :
    Qt Code:
    1. //the gui thread should wait here until the worker has finished
    2. m_background->wait();
    To copy to clipboard, switch view to plain text mode 

    It seems you want block the Gui thread during the processing. But how your progressbar should be managed and refreshed if the GUI thread is blocked ??

    You don't have to block the GUI thread, use QThread::finished() signal for manage post-treatement & cleaning once the processing is completed.

    'hope it will help you.
    Yes!
    That was the hint I needed!
    Thanks a lot!

Similar Threads

  1. busy progress bar without thread ?
    By npc in forum Newbie
    Replies: 34
    Last Post: 23rd July 2009, 09:29
  2. Display progress on another thread
    By radu_d in forum Qt Programming
    Replies: 1
    Last Post: 16th October 2007, 08:02
  3. Accessing data from a worker thread
    By steg90 in forum Qt Programming
    Replies: 20
    Last Post: 25th May 2007, 10:20
  4. KDE/QWT doubt on debian sarge
    By hildebrand in forum KDE Forum
    Replies: 13
    Last Post: 25th April 2007, 06:13
  5. Replies: 10
    Last Post: 20th March 2007, 22: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.