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. Is it possible to QProgressDialog::show without bringing the dialog to the front when the application is minimized/hidden?
Forum Updated to NodeBB v4.3 + New Features

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

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 4 Posters 1.2k Views 3 Watching
  • 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.
  • apalomerA Offline
    apalomerA Offline
    apalomer
    wrote on last edited by apalomer
    #1

    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();
    Chris KawaC 1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

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

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • apalomerA apalomer

        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();
        Chris KawaC Offline
        Chris KawaC Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on last edited by
        #3

        @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().

        1 Reply Last reply
        1
        • apalomerA Offline
          apalomerA Offline
          apalomer
          wrote on last edited by
          #4

          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.

          1 Reply Last reply
          0
          • R Offline
            R Offline
            random_ascii
            wrote on last edited by
            #5

            Did you find a solution? I have the same problem on Windows, Qt 5.9.1. I've also got the ShowWithoutActivating flag set on the QDialog.
            I've tried installing a native event handler and filtering out all the WM_ACTIVATE events, but that doesn't help.
            Something that might be related is that Qt seems to pop the main window to the front whenever you add a widget to something that doesn't already have a parent, so you have to be very careful about the order that things are created and added in. I'm not sure why this is, but experimentally it makes a difference in other parts of my app.

            R 1 Reply Last reply
            0
            • R random_ascii

              Did you find a solution? I have the same problem on Windows, Qt 5.9.1. I've also got the ShowWithoutActivating flag set on the QDialog.
              I've tried installing a native event handler and filtering out all the WM_ACTIVATE events, but that doesn't help.
              Something that might be related is that Qt seems to pop the main window to the front whenever you add a widget to something that doesn't already have a parent, so you have to be very careful about the order that things are created and added in. I'm not sure why this is, but experimentally it makes a difference in other parts of my app.

              R Offline
              R Offline
              random_ascii
              wrote on last edited by
              #6

              Actually I got this case to work by using these flags.

                      dialog->setAttribute(Qt::WA_ShowWithoutActivating);
                      dialog->setWindowFlags(Qt::WindowDoesNotAcceptFocus | Qt::FramelessWindowHint);
              
              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