我从文本文件中启动多个QProcesses(例如notepad.exe等不同的程序),并且想要定期检查它们是否仍在运行。
while循环不是解决方案,因为它阻止了ui-thread。 怎么能实现这一目标?在Java(Android)中,我会用asynctask来做这件事 连接到ScheduldExecutorService。类似的东西可用于qt吗?
这是我开始流程的地方:
void mywidget::startprocesses(QString &text)
{
QProcess *process = new QProcess(this);
this->myprocess.append(process);
process->start(text);
int state = process->state();
addlabelstatus(state);
}
这里的方法叫做:
while(!stream->atEnd()) //check stream until empty and assign line as a caption to a new QLabel
{
this->fileread = stream->readLine();
if(!this->fileread.isEmpty())
{
central->addlabel(this->fileread);
central->startprocesses(this->fileread);
}
}
void mywidget::addlabelstatus(QProcess::ProcessState newstate)
{
QString sstring;
if(newstate == 0)
{
QString sstring = "Wird nicht ausgeführt";
QLabel *label = new QLabel(sstring);
this->processstatus.append(label);
this->vrarea->addWidget(label);
}
else if (newstate == 1)
{
QString sstring = "Wird gestartet!";
QLabel *label = new QLabel(sstring);
this->processstatus.append(label);
this->vrarea->addWidget(label);
}
else if (newstate == 2)
{
QString sstring = "Wird ausgeführt!";
QLabel *label = new QLabel(sstring);
this->processstatus.append(label);
this->vrarea->addWidget(label);
}
else
{
QString sstring = "kein Status vorhanden!";
QLabel *label = new QLabel(sstring);
this->processstatus.append(label);
this->vrarea->addWidget(label);
}
}
答案 0 :(得分:4)
每个QProcess
都有finished(int exitCode, QProcess::ExitStatus exitStatus)
和stateChanged(QProcess::ProcessState newState)
个信号,这些信号在某个进程终止或更改时(按类型)发出。所以你的代码可以是:
.H方:
public slots:
void processFinished(int exitCode, QProcess::ExitStatus exitStatus);
void addlabelstatus(QProcess::ProcessState newState);
.CPP方:
void mywidget::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
<...>
}
void mywidget::addlabelstatus(QProcess::ProcessState newState)
{
switch(newState) {
<...>
};
}
// Your code change
QProcess *process = new QProcess(this);
this->myprocess.append(process);
connect(process, &QProcess::finished, this, &mywidget::processFinished);
connect(process, &QProcess::stateChanged, this, &mywidget::addlabelstatus);
process->start(text);
评论问题的更新
您可以尝试这种方式:
.H方
public slots:
void processFinished(QLabel *label, int exitCode, QProcess::ExitStatus exitStatus);
void addlabelstatus(QLabel *label, QProcess::ProcessState newState);
.CPP方
void mywidget::processFinished(QLabel *label, int exitCode, QProcess::ExitStatus exitStatus)
{
<...>
}
void mywidget::addlabelstatus(QLabel *label, QProcess::ProcessState newState)
{
switch(newState) {
<...>
};
}
while(!stream->atEnd()) {
this->fileread = stream->readLine();
if(!this->fileread.isEmpty()) {
QLabel *label = new QLabel(this->fileread);
QProcess *process = new QProcess(this);
this->myprocess.append(process);
connect(process, &QProcess::finished, [=]
(int exitCode, QProcess::ExitStatus exitStatus)
{ processFinished(label, exitCode, exitStatus); });
connect(process, &QProcess::stateChanged, [=]
(QProcess::ProcessState newState)
{ addlabelstatus(label, newState); });
process->start(text);
}
}
答案 1 :(得分:2)
while循环不是解决方案,因为它阻止了ui-thread。
正确。但是,由于Qt是一个事件驱动的框架,您可以使用计时器: -
// Assuming we have a list of processes QList<QProcess*> called timerList
QTimer* pTimer = new QTimer;
connect(pTimer, &QTimer::timeout, [=](){
foreach(QProcess* proc, timerList)
{
// get state
int state = process->state();
// update UI
addlabelstatus(state);
}
});
pTimer->start(1000); // every second
或者,当@someoneinthebox回答时,连接到每个QProcess的stateChanged信号,以便在发生时通知您并对此作出反应。