QProcess阻止UI更新

时间:2015-04-15 14:58:47

标签: c++ qt qprocess

我正在编写一个程序,在设备上启用WLAN驱动程序,然后搜索本地Wi-Fi连接。使用QProcess命令行打开驱动程序并执行扫描。这一切都很好;问题是我尝试在扫描发生之前更新UI,让用户知道发生了什么。这是代码:

ui->toolButton->setToolButtonStyle(Qt::ToolButtonTextOnly);
ui->toolButton->setText("Searching, please wait...");

// Enable WLAN drivers
QProcess process;
process.start(turn on WLAN);
process.waitForFinished();

// Get WLAN information for available networks
process.start("iwlist wlan0 scan");   // Find wireless access points
process.waitForFinished();
QString wirelessInfo = process.readAll();

简单地说,用户按下按钮开始扫描,我希望按钮改变文字说“#34;搜索,请等待......"在扫描开始之前,因为扫描完成需要几秒钟。

但是,在扫描开始之前,UI不会更新。系统只是显示锁定几秒钟,然后移动到程序的其余部分(这会打开一个带有Wi-Fi信息的单独窗口)。我尝试让线程在按钮文本更改和扫描之间休眠几秒钟,但结果是一样的。是否有理由在扫描开始之前文本不会更新,即使扫描在代码中的setText命令之后?

如果有帮助,我在Qt Creator中使用Ubuntu运行Qt 4.8.4。

2 个答案:

答案 0 :(得分:3)

UI被阻止,因为您在UI线程中调用了waitForFinished()。为避免这种情况,您可以:

  1. 不要调用waitForFinished(),而是连接到QProcess的finished()和error()信号。为此,您需要使QProcess成为类成员,以便在Qt返回事件循环时实例存活。这是"正常的做法。

  2. 将整个QProcess实例化和执行移动到另一个线程中。这稍微复杂一点,如果你有一个更复杂的控制流程涉及多个相互依赖的过程,那么这个过程可能是值得的。

答案 1 :(得分:0)

这绝不是一个理想的解决方案。但是,调用QApplication::processEvents()应该可以解决问题:

ui->toolButton->setText("Searching, please wait...");
QApplication::processEvents();