在QDialog :: exec()期间使用QThreads执行QWidget :: grab()

时间:2017-03-02 20:13:35

标签: c++ qt qthread qdialog

我编写了一个Qt程序,当用户上传某个数据文件并按下按钮时会生成一系列图表。按下按钮时,程序将计算一系列计算并绘制一些图形,并在函数调用QDialog::exec()的屏幕上显示它们。我想要实现的是grab使用QWidget::grab()生成的绘图的屏幕截图。所以基本上QWidget::grab()QDialog::exec()之后被调用。但由于QDialog::exec()一直运行直到用户关闭特定窗口,因此在关闭窗口后调用QWidget::grab()不会产生预期的结果。

这是我的代码的一部分;

mainwindow.cpp

    graphWindow.setWindowState(Qt::WindowMaximized);
    graphWindow.exec(); 
    graphWindow.savePlots();

graphWindow.savePlots()

void GraphWindow::savePlots()
{ 

  QStringList plotNames;
  plotNames << "Income Statement (Plot A)" << "Income Statement (Plot B)" << "Balance Sheet (Plot A)"
            << "Balance Sheet (Plot B)" << "Cash Flow Plot" << "Holistic Stock Performance";

  for(int item = 0; item < ui->graphTab->count(); item++)
  {
      ui->graphTab->setCurrentIndex(item);
      QWidget * currentWidget = ui->graphTab->widget(item);

      int height = currentWidget->height();
      int width = currentWidget->width();
      int x = currentWidget->x();
      int y = currentWidget->y();

      QRect grabRect(x,y,width,height);

      //destImagePath is a global variable
      QString imageFilePath = destImagePath;
      imageFilePath.append(plotNames.at(item));
      imageFilePath.append(".png");

      currentWidget->grab(grabRect).save(imageFilePath);
  }

     //Reset to first tab after grab
     ui->graphTab->setCurrentIndex(0);
 }

我在考虑通过运行另一个QDialog::exec()绕过QThreadGraphWindow::savePlots()在窗口仍在运行时执行QThread,以便屏幕抓取产生所需的结果。

有没有更好的方法呢?我认为创建一个新的QThreads只是为了调用一个函数是非常低效的。即使不是,您能否解释一下如何在并发var appSettings = ConfigurationManager.OpenExeConfiguration(System.Reflection.Assembly.GetEntryAssembly().Location).AppSettings; string setting = appSettings.Settings[strKeyName].Value; 中实现这一点。

1 个答案:

答案 0 :(得分:2)

在你的情况下,实际上没有必要使用QThread或使用QtConcurrent :: run,你可以使用

将一个调用排队到主线程上的一个插槽。
QTimer::singleShot(0, &graphWindow, &GraphWindow::savePlots);
graphWindow.exec();

在你的情况下的好处是,它将在主线程上运行,因此你不必为线程,同步和所有类似的捕获工作而烦恼(即使Qt更容易)。

这种方法的唯一限制是有效地&#34;冻结&#34;您在捕获期间的申请。考虑到它大大不到一秒钟,这通常应该是完全可以接受的。