PROBLEM DEFINITION: I have an external application called runSensor that communicates with a sensor. The sensor sends its data over UDP. Using the terminal, runSensor has two arguments to communicate with the sensor for data acquisition:start
and stop
.
Once at the terminal I call: $ runSensor start
, a sample output is as follows:
[Time 07:20:11:000]: Device PoweredOn.
[Time 07:20:11:010]: x=1.231, y=-0.022, z=0.001
[Time 07:20:11:015]: x=1.235, y=-0.024, z=0.001
[Time 07:20:11:020]: x=1.241, y=-0.024, z=0.002
[Time 07:20:11:025]: x=1.258, y=-0.027, z=0.002
I need to call start
and stop
using a QT-UI. For that, I have a QDialog as follows:
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
this->socketHandler = std::make_shared<udpHandler>();
this->runSensorStartProcess = std::make_shared<QProcess>();
this->runSensorStopProcess = std::make_shared<QProcess> ();
//--------------------------
// SIGNAL - SLOT
//--------------------------
connect(ui->startButton, SIGNAL(clicked()), this, SLOT(onStartButtonClicked()));
connect(ui->stopButton, SIGNAL(clicked()), this, SLOT(onStopButtonClicked()));
connect(this->socketHandler.get(), SIGNAL(sendUdpContent(QString)), this, SLOT(updateMessageBrowser(QString)));
connect(this->runSensorStartProcess.get(), SIGNAL(readyReadStandardError()), this, SLOT(printError()));
}
I use QProcess
to call the start and stop of runSensor application. When I push the GUI's start button, data acquisition starts, but the the GUI freezes and I cann't click on the stop button.
CODE EXTRACTS: Here is how I implemented the start button click:
void Dialog::onStartButtonClicked()
{
this->runSensorStartProcess->start("start");
//this->runSensorStartProcess->waitForFinished(-1);
//--------------------------
// udp socket handler starts picking data and write it into a file
//--------------------------
if (!this->runSensorStartProcess->waitForStarted())
{
qWarning() << "Warning: Cannot start Cygwin process!";
}
}
stop button click implementation is similar:
void Dialog::onStopButtonClicked()
{
if(this->runSensorStartProcess.get() != NULL)
{
this->runSensorStartProcess->close();
}
this->runSensorStopProcess->start("stop");
if (!this->runSensorStopProcess->waitForStarted())
{
qWarning() << "Warning: Cannot stop Cygwin!";
}
}
Question:
- How can I keep th GUI responsive after
runSensorStartProcess
starts? - How can I stop that process on demand (in fact by starting
runSensorStartProcess
)? - Do I need a separate
thread
forrunSensorStartProcess
?
Don't use any of the
waitForXxx
methods. That's all. Yes, it's that simple.Note that for every
waitForXxx
method there's a signal you can attach to and thus react to the event you're looking for.Aren't
QProcess::kill
andQProcess::terminate
what you need?Never. See also answer 1 and answer 2.