【问题标题】:GUI app frozen while process and generate a fileGUI 应用程序在处理和生成文件时冻结
【发布时间】:2021-09-26 23:23:00
【问题描述】:

我有一个 C++ 中的 QT GUI 应用程序,旨在处理和生成二进制文件。

应用程序运行良好,但是当它进入处理和写入文件的 while 循环时,它看起来像被冻结了。 我通过将 qApp->processEvents(); 处理到 while 循环中来解决这个问题。但问题是生成文件需要更多时间:

  • 在循环中没有qApp->processEvents(); => 需要 4 秒

  • qApp->processEvents(); 在循环中 => 完全相同的文件需要 50 秒

     for (unsigned long int k=0; k<DATASIZE ; k++){
    
     qApp->processEvents();
    
     /* Some process*/
     DataToFile.push_back(Process_Function(DATA));
    }
    /*Generating file*/
    myFile.write((char *)&DataToFile[0], DataToFile.size()*sizeof (float));
    
  • 数百万左右的数据量

  • Process_Function:取特定数据,计算值并返回。

问题:

1- 有没有办法处理数据,生成文件而不被冻结,也没有qApp-&gt;processEvents(); 的巨大延迟

2- 是否可以在另一个线程中运行qApp-&gt;processEvents();? / 或者还有其他方法吗?

【问题讨论】:

  • 使用后台线程生成文件;保持事件循环线程为事件打开。您可以使用信号报告进度信息。

标签: c++ qt user-interface


【解决方案1】:

首先,创建一个封装您的工作的对象:

class Generator : public QObject {
Q_OBJECT
  signals:
  void progress(float);
  void done();
  slots:
  void doWork() {
    QVector<float> DataToFile;
    for (unsigned long int k=0; k<DATASIZE ; k++){
        /* Some process*/
        DataToFile.push_back(Process_Function(DATA));
        if (k % 100 == 0) { // Inform the UI thread every 100 datapoints
            emit progress(k/DATASIZE); 
        }
    }
    myFile.write((char *)&DataToFile[0], DataToFile.size()*sizeof (float));
    emit done();
  }
};

然后创建一个新线程并让对象在那里工作:

QThread *t = new QThread(this);
Generator *g = new Generator;
g->moveToThread(t);
QObject::connect(t, &QThread::started, g, &Generator::doWork);
QObject::connect(g, &Generator::done, t, &QThread::quit);
QObject::connect(t, &QThread::finished, g, &QObject::deleteLater);
QObject::connect(t, &QThread::finished, t, &QThread::deleteLater);
t->start();

前两个connect 语句将生成器的生命周期与线程的生命周期联系起来,后两个语句在线程退出后清理所有内容。

当然你也可以连接Generator::progress信号来监控生成进度。

【讨论】:

  • doWorks 函数需要不同的参数,例如 DATA、计数器……我们可以在插槽中传递参数吗?
  • 要么将参数设置为生成器构造的一部分,要么使用 lambda:Object::connect(t, &amp;QThread::started, g, [=]() { g-&gt;doWork(123, "abc"); });
猜你喜欢
  • 2012-01-11
  • 2017-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多