繁体   English   中英

当应用程序最小化/隐藏时,是否可以在不将对话框置于前面的情况下进行 QProgressDialog::show?

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

我有一个应用程序,当您按下按钮时,它会依次启动两个进程。 两者都需要一些时间。 因此,对于用户来说,最小化我的应用程序的 window 或更改为另一个 window 以在他/她等待时执行某些操作是很重要的。 问题是,当第一个进程完成并且第二个进程启动时,会调用QProgressDialog::show并且小部件显示在操作系统中所有其他 windows 的顶部,从而改变用户在另一个软件中所做的任何事情的焦点。 我不希望这种情况发生。 我希望仅向父窗口小部件/应用程序显示进度对话框,但如果未显示应用程序(即它位于操作系统中的其他 window 后面),则不应将其置于前面。

这是一个重现我的问题的示例:

#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();
}

如果您编译示例,运行它并单击按钮,然后更改为其他程序,当第一个进程完成时,我的应用程序将再次出现在顶部。

一种选择是合并这两个进程,但这不是真正应用程序的解决方案,因为这两个进程由于第一个进程的触发而发生在不同的小部件中。 此外,第二个过程也可以自己完成......

关于如何向应用程序“显示”进度对话框但不会因为QProgressDialog::show而自动将应用程序带到前面的任何想法?

This happens to me in Ubuntu 18.04 with Qt 5.9.5, Qt 5.13.2, Qt 5.14.2 and Qt 5.15.0. 我还尝试使用 Windows 和 Qt 5.14.2 使用上述代码获得所需的行为。 在这里,您可以看到不需要的行为的礼物,首先是 Qt 5.13.2,然后是 Qt 5.9.5:

在此处输入图像描述

我也尝试过相同的非预期行为结果:

  • 使用QDialog::open代替QWidget::show
  • 使用QDialog::setVisible而不是QWidget::show
  • 添加progress->setAttribute(Qt::WA_ShowWithoutActivating); 在调用progress->show()之前。
  • 添加progress->setWindowFlag(Qt::WindowDoesNotAcceptFocus, true); 在调用progress->show();

你试过这个void QWidget::showMinimized()吗?

您可以通过处理QApplication::applicationStateChanged 信号来检查应用程序的 state 是什么

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM