私はクラスの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!");
}
}
'Qt :: DirectConnection'引数は不要です。自動接続は必要なものを正確に行います。コードを少なくしてより多くのマントラFTWを作成します。また、タイマーコンストラクタに明示的なnull親を与える必要はありません。単純に 'timer = new QTimer;'を使うか、クラスのメンバとして値によって 'QTimer'を保持するのが良いでしょう。最後に、 'destroyed'シグナルを' deleteLater'スロットに接続するのはナンセンスです。オブジェクトはすでに破壊されています。後で削除する必要はありません! –
これは、実際問題を引き起こすコードがないので、非常に貧しい質問です。あなたの問題はタイマーとは関係なく、 'RestartStoppedProcess'スロットがやっていることと関係があります。 'RestartStoppedProcess'のコードを表示するまで、この質問は不十分なままであり、不十分な情報のために閉鎖されることがあります。問題に**完全な**コードを提供しようと努力する。 –