qt - QProgressBar如何表达QProcess的延迟操作?
问题描述
我使用 QProcess 调用 Ping 命令,并使用 waitForFinished 等待命令执行结束。现在想用一个QProgressBar进度条connect_gress来表示初始状态的范围是(0, 100),当QProcess开始启动的时候就变成了(0, 0),也就是busy状态,命令调用由 QProcess 结束。时间变回 (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);
}
这是 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);
但是程序运行的时候,我按下按钮,主界面的connect_gress并没有进入busy状态,直到命令结束,connect_gress的值会变成100,也就是gress_finish执行成功,显示成功, gress_start 也是执行了,但是没有成功显示。
解决方案
QProcess::waitForFinished阻塞当前线程。我相信你在主线程又名 GUI 线程中调用它。所以主线程永远不会改变处理事件,包括paintEvent。在 ping 进程运行时 GUI 也被冻结。所以用户此时不能做任何事情,我不知道这是否是你的意图。
解决它的最简单方法根本不等待完成。但在这种情况下,用户可以在 ping 时玩弄 ui。excping
是一个堆栈变量,因此在这种情况下它可能会在发出完成之前死亡。我们可以在堆中创建它并在完成信号后删除。
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
另一种解决阻塞的简单方法是强制事件循环处理事件。我不赞成processEvents。文档也不鼓励使用它。所以请不要养成像某种魔法酱一样折腾的习惯。
void web::gress_begin(){
ui->connect_gress->setRange(0, 0);
QCoreApplication::processEvents();
}
您还可以调整函数的执行延迟。签出 Qt::QueuedConnection和QMetaObject::invokeMethod。
推荐阅读
- wordpress - 滚动时关闭弹出窗口
- javascript - 如何使用 aws4 为 amazon spapi 做正确的请求签名?
- angular - 使用 abp 和 angular 自动完成
- typescript - VS代码交互式视图和更新单元格的问题
- arrays - 我得到的结果是“未定义”,可能是 JSON 数据存在问题,其中数据为数组格式。我该如何解决这个问题?
- javascript - React-router Route 不渲染组件
- python - 与 PyTorch 相比,Numpy 有限差分计算速度非常慢
- bash - 计算文件中模式的出现次数,包括零以表示缺失的模式
- javascript - 在使用 window.print() 下载之前获取文件副本
- javascript - 在 React 中解压缩 JSON 文件夹并解析它们