Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-17427

QProgressDialog use of QElapsedTimer wrong, causes dialog not to show

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P4: Low
    • None
    • 4.7.0, 4.7.1, 4.7.2
    • None
    • Windows (XP SP3), VC2008, QT 4.7.2

    Description

      In this commit:
      http://qt.gitorious.org/qt/qt/commit/0f771c62f5253a969f5a8a81bfd9254b9bd58b8f

      QTime was Replaced by QElapsedTimer. One effect of this that was missed (I think!) for QProgressDialog is that a timer needs to be started, while a QTime doesn't (or more correct: QTime seems to have fallback). There are ways to end up using the timer without starting it in the current QProgressDialog, that appear to me to be normal usage of QProgressDialog. When this happens, it causes the dialog to not show up automatically, in some cases (depending on the value in uninitialized memory).
      Note: I'm guessing this is also the cause for QTBUG-9600 .

      Looking at the QProgressDialog code
      ===================================

      The timer is only started in QProgressDialog::setValue :

      if (progress == 0) {
                  d->starttime.start();
      

      however, if you never pass a 0 progress (and this usually happens if you try to do progress for networking, e.g. QHttp etc), or even if you do setValue(0) without setting the maximum higher than 0 first (e.g.in the cases where QHttp does not return a 'total' so there is no maximum to set), the QElapsedTimer d->starttime is never started. On the first setValue of something bigger than 0, this happens:

                  int elapsed = d->starttime.elapsed();
                  if (elapsed >= d->showTime) {
                      need_show = true;
      

      and the windows implementation of elapsed() returns getTickCount() - t1, where t1 is not initialized memory if the timer was not start()-ed (0xcdcdcdcd on windows with DEBUG_NEW).

      Workaround: artificially bypass the problems in QProgressDialog code by calling setMaximum(1), then setValue(0), then setMaximum(0) (the last one is needed if you don't know the real maximum, e.g. in the download case where the http server does not return the size).

      Code Fix:

      • fix QElapsedTimer to work more like QTime? Eg QTime's ds():
             inline int ds() const { return mds == -1 ? 0 : mds; }
        

        This seems to check if it has been started/initliased/...?

      • move d->starttime.start(); before the 'if (progress == 0)', or even to creation? Or check if the timer has already been started (QElapsedTimer::isValid() I think)?
      • some other change to QProgressDialog code to avoid this situation.

      Test Code
      =========

      Take the code from the QProgressDialog help, and replace the initial value of steps with 1:

       // Operation constructor
       Operation::Operation(QObject *parent)
           : QObject(parent)
           , steps(1) //NOTE 1, and no dialog is ever shown, 0 and it's ok
       {
           pd = new QProgressDialog("Operation in progress.", "Cancel",0,100);
           connect(pd, SIGNAL(canceled()), this, SLOT(cancel()));
           t = new QTimer(this);
           connect(t, SIGNAL(timeout()), this, SLOT(perform()));
           t->start(100);
       }
      
      
       void Operation::perform()
       {
           pd->setValue(steps);
           //... perform one percent of the operation
           steps++;
           if (steps > pd->maximum())
               t->stop();
       }
      
       void Operation::cancel()
       {
           t->stop();
           //... cleanup
       }
       

      Attachments

        1. main.cpp
          1 kB
        2. QTBUG-17427.JPG
          QTBUG-17427.JPG
          154 kB
        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            dfaure David Faure (Private)
            legolas Arnt Witteveen
            Votes:
            1 Vote for this issue
            Watchers:
            7 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes