0

I use QProcess to call the Ping command, and use waitForFinished to wait for the end of the command execution. Now I want to use a QProgressBar progress bar connect_gress to indicate that the range is (0, 100) in the initial state, and it becomes (0, 0) when QProcess starts to start, which is the busy state, and the command called by QProcess ends. Time to change back to (0, 100)

void web::gress_begin(){
ui->connect_gress->setRange(0, 0);
}

void web::gress_finish(){
ui->connect_gress->setRange(0, 100);
ui->connect_gress->setValue(100);
}

This is part of QProcess

QProcess excping;

connect(&excping, SIGNAL(started()), this, SLOT(gress_begin()));
connect(&excping, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(gress_finish()));

excping.start(cmdstr);
excping.waitForStarted();
excping.waitForFinished(-1);

But when the program is running, I press the button, the connect_gress on the main interface does not enter the busy state, and until the command ends, the value of connect_gress will become 100, that is, gress_finish is executed and successfully displayed, and gress_start is also It was executed, but it did not show up successfully.

1 Answers1

0

QProcess::waitForFinished blocks the current thread. And I believe you are calling it in main tread aka GUI thread. So main thread never has a change to process events including paintEvent. Also GUI is frozen while ping process running. So user can't do anything at this time, I don't know if it is your intend or not.

Easiest way to solve it not waiting for finish at all. But in this case user can play around with ui while pinging. excping is a stack variable so it might die before emitting finished in this case. We can create it in heap and delete after the finished signal.

auto excping = new QProcess(this);

connect(excping, SIGNAL(started()), this, SLOT(gress_begin()));
connect(excping, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(gress_finish()));
connect(excping, SIGNAL(finished(int, QProcess::ExitStatus)), excping, SLOT(deleteLater()));

excping->start(cmdstr);
excping->waitForStarted();
// no waitForFinished

Another easy way to solve with blocking is forcing event loop to process events. I am not a favor of processEvents. Documentations also discourage to use that. So please don't make it habit to toss around like a some sort of magic sauce.

void web::gress_begin(){
    ui->connect_gress->setRange(0, 0);
    QCoreApplication::processEvents();
}

Also you can tweak around with the execution delay of functions. Checkout Qt::QueuedConnection and QMetaObject::invokeMethod.

Kao
  • 537
  • 5
  • 12