我正在使用QProcess运行wscript来运行VB脚本,该脚本将Excel文件转换为制表符分隔的文本文件。该脚本运行良好,但是GUI冻结,用户无法与其进行大量时间的交互。这是代码:
/* Create txt files and store paths */
for (int i = 0; i < excelFilepaths.size(); ++i) {
wscript->start("wscript.exe", QStringList() << vbs.fileName() << excelFilepaths.at(i) << newDir.absolutePath() + "/" + QString::number(i + 1));
wscript->waitForFinished();
payloadPaths.push_back(newDir.absolutePath() + "/" + QString::number(i + 1));
}
最近发生的事情是我有多个excel文件路径和堆上分配的QProcess。此QProcess运行VB脚本,将excel文件转换为文本文件,然后存储新文本文件的路径。这需要很长时间(4个excel文件大约需要20秒)。在此期间,GUI被冻结。我希望用户能够使用不干扰过程的GUI部分。
现在我怀疑这个问题的原因是
QProcess::waitForFinished()
我已经在线阅读有关连接QProcess的finished()和error()信号以解决此问题的信息。但是我一直很难这样做。我正在运行此代码作为继承自QObject并包含Q_OBJECT宏的类的方法,因此应该设置所有内容。我只是需要一些帮助将剩下的部分组合在一起。我怎样才能使它在QProcess运行时我的GUI不会冻结?请帮忙。
答案 0 :(得分:1)
我遇到了同样的问题但 QSerialPort 。但是,我认为解决方案是一样的。我找不到让“serial-&gt; waitForReadyRead()”不冻结GUI的方法,所以,我实现了自己的功能。
void Research::WaitSerial(int MilliSecondsToWait)
{
QTime DieTime = QTime::currentTime().addMSecs(MilliSecondsToWait);
flag = 0;
while(QTime::currentTime() < DieTime && !flag)
{
QCoreApplication::processEvents(QEventLoop::AllEvents,100);
if(BufferSerial != "")
{
flag++;
}
}
}
当然,你的问题很相似但不一样。只需更改if
即可获得“停止条件”。希望这会有所帮助。
答案 1 :(得分:1)
引用名为Synchronous Process API的部分的文档:
waitForStarted()
阻止,直到流程开始。waitForReadyRead()
阻止,直到新数据可用于在当前读取通道上读取。waitForBytesWritten()
阻塞,直到将一个数据有效负载写入进程。waitForFinished()
阻止,直到流程结束。从主线程(调用QApplication :: exec()的线程)调用这些函数可能会导致用户界面冻结。
记住这一点。但是,您可以使用that:
之类的内容克服此问题connect(process, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
[=](int exitCode, QProcess::ExitStatus exitStatus){ /* ... */ });
请注意,还有一些signals可能符合任何目的。