2017-06-06 1 views
-3

私はクラスのctorに新しいQTimerオブジェクトを作成しました。アプリケーションが起動すると、タイマーも指定された時刻に開始します。このタイマーはすべてのプロセスIDのトラックを保持しており、特定のprocess-idがアクティブでない(タスクマネージャーから強制終了されている)ことが分かった場合は、そのプロセスを再起動します。問題は私のアプリケーションがこのQTimerオブジェクトのために少し遅れていることです。タイムアウト後に限り、アプリケーションは円滑になります。しかし、5秒後に再びタイマーが始まり、アプリケーションは再び遅れを開始します。 QTimerオブジェクトをクラスのctorから離れて起動するための最良の方法は何ですか? UIスレッドでGUIがハングしないようにQTimerを起動する方法 - RestartStoppedProcess() - コード

qTimer = new QTimer(0); 

connect(qTimer, SIGNAL(timeout()), this, SLOT(RestartStoppedProcess()), Qt::DirectConnection); 
connect(qTimer, SIGNAL(destroyed()), qTimer, SLOT(deleteLater()), Qt::DirectConnection); 

qTimer->setTimerType(Qt::VeryCoarseTimer); 
qTimer->start(5000); 


void ProcessMonitor::RestartStoppedProcess() 
{ 
    try 
    { 
     QProcess *objMonitorProcess = new QProcess(this); 
     connect(objMonitorProcess, SIGNAL(finished(int,QProcess::ExitStatus)), objMonitorProcess, SLOT(deleteLater())); 
     for(int i = 0; i < ui->twShowProcess->rowCount(); i++) 
     { 
#ifdef Q_WS_LIN 
      //   objMonitorProcess->start("pidof", QStringList() << (ui->twShowProcess->item(i, 0)->text()), QIODevice::ReadOnly); 
      objMonitorProcess->start("pidof "+ (ui->twShowProcess->item(i, 0)->text()), QIODevice::ReadOnly); 
#elif Q_WS_WIN 
      QString cmd("wmic process where "); 
      QString qszFilters("\"processid=\'"); 
      QString qszSubFilters = qszFilters.append(ui->twShowProcess->item(i, 1)->text().append("\'").append("\"").append(" get name")); 
      cmd.append(qszSubFilters); 
      objMonitorProcess->start(cmd.toStdString().c_str(), QIODevice::ReadOnly); 
#else 
      QString qszProcessName = ui->twShowProcess->item(i, 0)->text().split(".").takeFirst(); 
      objMonitorProcess->start("pgrep", QStringList() << qszProcessName, QIODevice::ReadOnly); 
#endif 
      if((objMonitorProcess->waitForStarted(4000) == true) && (objMonitorProcess->state() == QProcess::Running)) 
      { 
       if(objMonitorProcess->waitForFinished(3000) == false) 
        continue; 
       else 
       { 
        QString qszProcessStatus = ui->twShowProcess->item(i, 3)->text(); 
        if(qszProcessStatus.compare("Running") == 0) 
        { 
         QString qszStandardOutput, qszStandardError; 
         qszStandardOutput.clear(); qszStandardError.clear(); 
         qszStandardOutput = QString(objMonitorProcess->readAllStandardOutput()); 
         qszStandardError = QString(objMonitorProcess->readAllStandardError()); 
         if(qszStandardError.simplified().compare("No Instance(s) Available.", Qt::CaseInsensitive) == 0 && qszStandardOutput.simplified().isEmpty() == true) 
         { 
          ui->twShowProcess->selectRow(i); 
          if(ui->twShowProcess->selectedItems().at(0)->text().compare("LTtagdb.exe", Qt::CaseInsensitive) == 0 || 
            ui->twShowProcess->selectedItems().at(0)->text().compare("LTmessagebroker.exe", Qt::CaseInsensitive) == 0) 
           this->StopAllApplicationsForcefully(); 
          else 
           this->on_actionStop_triggered(); 

          if(this->ptrobjContextMenu->isVisible()) 
           this->ptrobjContextMenu->close(); 

          ui->twShowProcess->clearSelection(); 

          if(mobj_ProcessLogMap.mobj_ProcessAndLogMapping.contains(ui->twShowProcess->item(i, 8)->text()) == true) 
          { 
           mobj_ProcessLogMap.mobj_ProcessAndLogMapping.remove(ui->twShowProcess->item(i, 8)->text()); 
           mobj_ProcessLogMap.mobj_ProcessAndLogMapping.insert(ui->twShowProcess->item(i, 8)->text(), QString("")); 
          } 
          else 
           this->mobj_ProcessLogMap.mobj_ProcessAndLogMapping.insert(ui->twShowProcess->item(i, 8)->text(), QString("")); 
         } 

         if(ui->twShowProcess->item(i, 0)->text() == "LThistdb.exe") 
         { 
          if(IsServiceRunning(QString("LThistdb.exe")) == false) 
           this->on_actionStopPostgreSQL_DB_Server_triggered(); 
         } 
         qszStandardOutput.clear(); 
        } 
       } 
      } 
      else 
       break; 
#ifdef Q_WS_WIN 
      cmd.clear(); 
      qszFilters.clear(); 
      qszSubFilters.clear(); 
#endif 
     } 
    } 
    catch(QProcess::ProcessError pError) 
    { 
     QMessageBox objCrashExit; 
     objCrashExit.information(this, "Crashed", "Process error returned code: " + QString::number(pError)); 
    } 
    catch(...) 
    { 
     QMessageBox objCrashExit; 
     objCrashExit.information(this, "Unknown Crash", "Unknown crash exit-child process may not be running correctly!"); 
    } 
} 
+0

'Qt :: DirectConnection'引数は不要です。自動接続は必要なものを正確に行います。コードを少なくしてより多くのマントラFTWを作成します。また、タイマーコンストラクタに明示的なnull親を与える必要はありません。単純に 'timer = new QTimer;'を使うか、クラスのメンバとして値によって 'QTimer'を保持するのが良いでしょう。最後に、 'destroyed'シグナルを' deleteLater'スロットに接続するのはナンセンスです。オブジェクトはすでに破壊されています。後で削除する必要はありません! –

+0

これは、実際問題を引き起こすコードがないので、非常に貧しい質問です。あなたの問題はタイマーとは関係なく、 'RestartStoppedProcess'スロットがやっていることと関係があります。 'RestartStoppedProcess'のコードを表示するまで、この質問は不十分なままであり、不十分な情報のために閉鎖されることがあります。問題に**完全な**コードを提供しようと努力する。 –

答えて

0

QTimer実行それが実行に時間がかかる場合、あなたのUIブロックそれはそう。

QtConcurrent::run(yourProcessingFunction); 

あなたが明らかにすることができます:簡単な解決策は、Qtの中でQTimerから呼び出され、あなたのタイムアウトスロットからこのようQtConcurrent::runを使用している可能性があることを行うための最も簡単な方法、ちょうど別のバックグラウンドスレッドでは、あなたの「処理」のものを実行することです独自のスレッドを作成し、QTimerのビルドをQObject::startTimer(...)から使用しますが、これは通常より多くの作業です。

0

問題は、作業量がRestartStoppedProcessである可能性があります。 documentation for QTimer状態として

と呼ばれるスロットを論じる場合:

常に迅速に返すように書かれるべきであるQtがにイベントを配信することができるように(典型的には1つのデータ項目を処理した後)ユーザーインターフェイスを開き、すべての作業を完了したらすぐにタイマーを停止します。

メインスレッドでQTimerという大きな負荷がかかると、Guiで遅延が発生する可能性があります。 Qtのドキュメントは状態に移行:

これは、GUIアプリケーションで重い作業を実施するための伝統的な方法ですが、マルチスレッドは、今日より多くのプラットフォームで利用できるようになっているとして、我々はゼロミリ秒QTimerオブジェクトが徐々にすることを期待しますQThreadsに置き換えられます。

これを念頭に置いて、RestartStoppedProcessが別のスレッドで機能するようにコードをリファクタリングすることをお勧めします。 "How to Really Truly Use QThread" hereに関する素晴らしいチュートリアルがあります。

関連する問題