Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Which is the proper way to update Qprogressbar from a widget
QtWS25 Last Chance

Which is the proper way to update Qprogressbar from a widget

Scheduled Pinned Locked Moved General and Desktop
11 Posts 3 Posters 5.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • dheerendraD Offline
    dheerendraD Offline
    dheerendra
    Qt Champions 2022
    wrote on last edited by
    #2

    Signals and Slots is the best way to update the same. Since you are doing everything inside the main thread(painting and updating the progress bar), you need to process the events locally. Program may be crashing due to some wrong values or huge values.

    You can try something like following. Just simulated your scenario.

    @void Widget::paintEvent(QPaintEvent *){
    int count=10;
    qDebug() << "Painting"<<endl;
    for (int i=0; i<100000000;i++){
    if (i ==0){
    qDebug() << " i="<<i << endl;
    QThread::sleep(1);
    updateprogbar(count);
    count+=10;
    }
    }
    }

    void Widget::updateprogbar(int i){
    qDebug() << " UpdateBar="<<i << endl;
    QEventLoop loop;
    this->bar->setValue(i);
    loop.processEvents();
    }
    @

    Dheerendra
    @Community Service
    Certified Qt Specialist
    http://www.pthinks.com

    1 Reply Last reply
    0
    • A Offline
      A Offline
      andreyc
      wrote on last edited by
      #3

      @
      void dlgGraph::showDrawingProgress(int t,int i)
      {
      qDebug()<< i;
      progressBar->setMaximum(t);
      progressBar->setValue(i);//->CRASH
      }
      @

      May be a silly question but have you allocated progressBar ?
      Another question is why do you set maximum on each call to showDrawingProgress?
      One time before starting a loop is enough.
      What are values of t and i in showDrawingProgress when it crashes?
      Does it crash immediately on a first call or after some time?

      I would suggest to connect QProgressBar::setRange and QProgressBar::setValue to the signals in mapframe and them emit setRange before starting a loop and emit setValue in the loop.

      1 Reply Last reply
      0
      • dheerendraD Offline
        dheerendraD Offline
        dheerendra
        Qt Champions 2022
        wrote on last edited by
        #4

        Good point andreyc. I did not suspect on ProgressBar allocation as the crash is in setValue. If it crashes at line#, allocation should be definitely a problem and it should crash every time.

        Dheerendra
        @Community Service
        Certified Qt Specialist
        http://www.pthinks.com

        1 Reply Last reply
        0
        • M Offline
          M Offline
          marceloarguello700
          wrote on last edited by
          #5

          The progresbar is outside of widget.
          What mean allocated,
          i add the progress to the layout:

          @
          progressBar = new QProgressBar() ;
          progressBar->setRange(0,100);
          mainLayout->addWidget(progressBar);
          @

          Now in mapframe.h split the signal and add another signal to setBarMaxValue
          before the for init.

          @
          void progressMaxValue(int);
          void progressDrawValue(int);
          @

          In the main window connect the signal to slot
          @
          connect( mapframe, SIGNAL( progressDrawValue(int ) ),
          this, SLOT( setBarValue( int ) ) );
          connect( mapframe, SIGNAL( progressMaxValue(int) ),
          this, SLOT( setBarMaxValue( int ) ) );
          @

          The paint even of the MapFrame widget emit the signal progressMaxValue
          before starting the for loop.

          @
          void MapFrame::drawPointFeatures(QPainter *painter)
          {

          if (m_PointFeatures.size()>0)
          {
          emit progressMaxValue(m_PointFeatures.size());
          }
          for (int i=0;i<m_PointFeatures.size();i++)
          {
                painter->setBrush(m_PointFeatures.at(i).color);
                painter->drawEllipse(translator.mapToPixel(m_PointFeatures.at(i).x,m_PointFeatures.at(i).y), 3, 3);          
                if( 1 % 1000==0) emit progressDrawValue(i);
          }
          

          }
          @

          It crash in the first emit when i=0
          Greetings

          1 Reply Last reply
          0
          • A Offline
            A Offline
            andreyc
            wrote on last edited by
            #6

            Do you work on Windows on OSX, Linux?
            If OSX,Linux could show a backtrace for the crash?
            I don't know how to get backtrace on Windows but if you know how then it may help here.

            1 Reply Last reply
            0
            • A Offline
              A Offline
              andreyc
              wrote on last edited by
              #7

              [quote author="marceloarguello700" date="1410970001"]
              The progresbar is outside of widget.
              What mean allocated,
              i add the progress to the layout:

              @
              progressBar = new QProgressBar() ; // <<-- here is allocation
              progressBar->setRange(0,100);
              mainLayout->addWidget(progressBar);
              @
              [/quote]

              Yes, you allocated a progress bar

              [quote author="marceloarguello700" date="1410970001"]
              @
              void MapFrame::drawPointFeatures(QPainter *painter)
              {

              if (m_PointFeatures.size()>0)
              {
              emit progressMaxValue(m_PointFeatures.size());
              }
              for (int i=0;i<m_PointFeatures.size();i++)
              {
                    painter->setBrush(m_PointFeatures.at(i).color);
                    painter->drawEllipse(translator.mapToPixel(m_PointFeatures.at(i).x,m_PointFeatures.at(i).y), 3, 3);          
                    if( 1 % 1000==0) emit progressDrawValue(i);
              }
              

              }
              @
              [/quote]

              I guess it is a type in the comment and in the source code you have
              @
              if( i % 1000==0) emit progressDrawValue(i);
              @

              instead of
              @
              if( 1 % 1000==0) emit progressDrawValue(i);
              @

              1 Reply Last reply
              0
              • M Offline
                M Offline
                marceloarguello700
                wrote on last edited by
                #8

                Thanks for the reply,
                I run over window

                My original code is with i, dont know, why appear a one (1)
                @
                if( i % 1000==0) emit progressDrawValue(i);
                @

                the question is what need to make to avoid crashing?

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  andreyc
                  wrote on last edited by
                  #9

                  You may try to connect the progressDrawValue and progressMaxValue directly to QProgressBar

                  @
                  connect( mapframe, SIGNAL( progressDrawValue(int ) ),
                  progressBar, SLOT( setValue( int ) ) );
                  connect( mapframe, SIGNAL( progressMaxValue(int) ),
                  progressBar, SLOT( setMaximum( int ) ) );
                  @

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    marceloarguello700
                    wrote on last edited by
                    #10

                    I try like you suggest but crash in the firts emit

                    According to this page
                    http://qt-project.org/doc/qt-4.8/threads-qobject.html

                    If you are calling a function on an QObject subclass that doesn't
                    live in the current thread and the object might receive events,
                    you must protect all access to your QObject subclass's internal
                    data with a mutex; otherwise, you may* experience crashes* or other undesired behavior.

                    May be it is the cause, but i dont know how fix it.

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      andreyc
                      wrote on last edited by
                      #11

                      Do you have MapFrame::drawPointFeatures and QProgressBar in separate threads ?

                      If so, then it will not work. All UI related classes must be used in a "main thread":http://qt-project.org/doc/qt-5/threads-qobject.html#qobject-reentrancy.

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved