2016-07-25 25 views
1

QProcessでwscriptを実行して、Excelファイルをタブ区切りのテキストファイルに変換するVBスクリプトを実行しています。スクリプトは正常に実行されますが、GUIはフリーズし、ユーザーはかなりの時間にわたってスクリプトを操作できません。GUIがフリーズするのを止めるにはQProcessでwaitForStartedを避けるには?

/* 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は、Excelファイルをテキストファイルに変換し、新しいテキストファイルのパスを保存するVBスクリプトを実行します。これには長い時間がかかります(4つのExcelファイルで約20秒)。この間、GUIはフリーズします。私は、ユーザーがプロセスに干渉しないGUIの部分を使用できるようにしたいと思います。

は、今私は、この問題の原因は

QProcess::waitForFinished() 

であり、私はこの問題を取り除くために)完成()とエラー(接続に関するオンラインQProcessの信号を読んだと思われます。しかし、私はそうすることが困難でした。 QObjectから継承し、Q_OBJECTマクロを含むクラスのメソッドとしてこのコードを実行しているので、すべてを設定する必要があります。私はちょうど一緒に作品の残りの部分を置くいくつかの助けが必要です。 QProcessの実行中にGUIがフリーズしないようにするにはどうすればよいですか?助けてください。

+1

*しかし、私はこれをやっているのが難しかった*あなたは何を試しましたか?何が失敗した? – peppe

+4

* "QProcessの実行中にGUIがフリーズしないようにするにはどうしたらいいですか?" * - "QProcessの*終了信号(*)と*"信号をローカルスロットに接続し、同期 'waitForFinished'コール。 – IInspectable

+0

どうすればそれらの信号を接続できますか?どのようにこれは私の問題を排除しますか?私はconnect(process、&QProcess :: finished、this、&CustomClass :: slotHere)のような何かをすると思います。または、カスタムスロットを取り除いて接続することができます(プロセス、&QProcess :: finished、lambdaHere)。例は非常に役に立ちます – Dillydill123

答えて

1

Synchronous Process APIと呼ばれるセクションでの文書を引用する:プロセスが開始されるまで

  • waitForStarted()ブロック。
  • waitForReadyRead()現在の読み出しチャネルで新しいデータを読み取ることができるまでブロックします。
  • waitForBytesWritten()ブロックは、1つのペイロードのデータがプロセスに書き込まれるまでブロックします。
  • waitForFinished()プロセスが終了するまでブロックします。

これらの関数をメインスレッド(QApplication :: exec()を呼び出すスレッド)から呼び出すと、ユーザーインターフェイスがフリーズすることがあります。

これを覚えておいてください。

connect(process, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), 
[=](int exitCode, QProcess::ExitStatus exitStatus){ /* ... */ }); 

注任意の所望の目的を、スイート可能性があるsignalsいくつかのより多くがあること:しかし、あなたはthatのようなものを使用してこの問題を克服することができます。

1

私は同じ問題があったが、QSerialPortであった。しかし、私は解決策は同じだと思います。私は "シリアル - > 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を「停止条件」に変更してください。お役に立てれば。


編集:これはもともと私のイデアではありませんでした。私はどこかのフォーラムでそれを見つけました。だから私はクレジットを取らない。

+3

ポーリングは、いつものように、2番目に優れたソリューションです。 Qtはイベントベースのフレームワークを駆動するために[signals&slots](http://doc.qt.io/qt-5/signalsandslots.html)を使用しています。 – IInspectable

+0

ここで何が起こっているのか説明できますか? QProcessの実行中に手動でプログラムを停止しているようです。あれは正しいですか? – Dillydill123

+0

@ Dillydill123さて、はい。私はそれを正確にやっています。私はシリアルが何かを送るまでプログラムを停止します。私の場合は 'WaitForReadyRead'と同じです。私は信号とスロットでそれを行う方法を知らない、申し訳ありません。 – andseg

関連する問題