Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Is it possible to QProgressDialog::show without bringing the dialog to the front when the application is minimized/hidden?



  • I have an application that when you press a button it launches two processes one after the other. Both take some time. So it is topical for the user to minimize the window of my app or change to another window to do something while he/she waits. The problem is that when the first process finishes and the second one starts,QProgressDialog::show is called and the widget is shown on top of all other windows in the os, changing the focus of whatever the user is doing in another software. I do not want that to happen. I want the progress dialog to be shown only to the parent widget/application, but if the application is not shown (i.e. it is behind some other window in the os) it should not be brought to the front.

    Here is an example that reproduces my problem:

    #include <QApplication>
    #include <QGridLayout>
    #include <QLabel>
    #include <QProgressDialog>
    #include <QPushButton>
    #include <QTimer>

    #define WAIT_TIME_MS 3000
    
    QProgressDialog* createProgress(const QString& title, QWidget* parent = nullptr)
    {
      QProgressDialog* progress = new QProgressDialog(title, "", 0, 0, parent);
      progress->setWindowTitle("Progress dialog");
      progress->setWindowFlag(Qt::CustomizeWindowHint, true);
      progress->setWindowFlag(Qt::WindowCloseButtonHint, false);
      progress->setWindowFlag(Qt::WindowContextHelpButtonHint, false);
      progress->setWindowModality(Qt::WindowModal);
      progress->setCancelButton(nullptr);
      progress->show();
      return progress;
    }
    
    int main(int argc, char** argv)
    {
      // Create application
      QApplication app(argc, argv);
    
      // Create widget
      QWidget* w = new QWidget;
      w->setLayout(new QGridLayout);
      w->setMinimumSize(QSize(800, 600));
    
      // Add button
      QPushButton* pb = new QPushButton("Push to compute");
      w->layout()->addWidget(pb);
    
      // Add label
      w->layout()->addWidget(new QLabel("Compile version: " + QString::fromUtf8(QT_VERSION_STR)));
      w->layout()->addWidget(new QLabel("Runtime version: " + QString::fromUtf8(qVersion())));
    
      // Connect push button click
      QObject::connect(pb, &QPushButton::clicked, pb, [w]() {
        // Create first progress dialog
        QProgressDialog* progress_1 = createProgress("First progress dialog", w);
    
        // After WAIT_TIME_MS milliseconds show the progress dialog
        QTimer::singleShot(WAIT_TIME_MS, [w, progress_1]() {
          // Close previous progress
          progress_1->hide();
          progress_1->deleteLater();
    
          // Create progress dialog
          QProgressDialog* progress_2 = createProgress("Second progress dialog", w);
    
          // Hide and destory progress dialog after WAIT_TIME_MS more milliseconds
          QTimer::singleShot(WAIT_TIME_MS, [progress_2]() {
            progress_2->hide();
            progress_2->deleteLater();
          });
        });
      });
    
      w->show();
      return app.exec();
    }
    

    If you compile the example, run it and click the button, and after that change to some other program, when the first process finishes my app will appear again on top.

    One option would be to merge the two processes, but it is not a solution for the real application as the two processes happen in different widgets as a result of a trigger of the first process. Moreover, the second process can be done by itself as well...

    Any idea on how to "show" the progress dialog to the application but not bring the application to the front automatically as a consequence of that QProgressDialog::show?

    This happens to me in Ubuntu 18.04 with Qt 5.9.5 as well as with Qt5.13.2. I have tried with Windows and Qt 5.14.2 with the desired behaviour with the code as is above. Here you can see a gift of the behavior that is not desired, first with Qt 5.13.2 and then with Qt 5.9.5:
    alt text

    I have also tried with the same non-desired behaviour result:

    • Using QDialog::open instead of QWidget::show.
    • Using QWidget::setVisible instead of QWidget::show.
    • Adding progress->setAttribute(Qt::WA_ShowWithoutActivating); before calling show().
    • Adding progress->setWindowFlag(Qt::WindowDoesNotAcceptFocus, true); before calling show();

  • Lifetime Qt Champion

    Hi,

    Can you add the Qt version as well as the OS you are running on ?


  • Moderators

    @apalomer said:

    Any idea on how to "show" the progress dialog to the application but not bring the application to the front automatically as a consequence of that QProgressDialog::show?

    That's actually how it behaves for me on Windows. Might be your OS/Qt version thing, as @SGaist hinted at.
    In any case you can try to add progress->setAttribute(Qt::WA_ShowWithoutActivating); before calling show().



  • I have tried this with Ubuntu 18.04 and Qt 5.9.5 as well as Qt 5.13.2. I've updated my original question to include this as well as a giff of what happens.


Log in to reply