QProcess 阻止 UI 更新
QProcess preventing UI updates
我正在编写一个程序来启用设备上的 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();
简而言之,用户按下一个按钮开始扫描,我希望按钮在扫描开始前将文本更改为 "Searching, please wait...",因为扫描需要几秒钟才能完成。
但是,UI 不会在扫描开始前更新。系统只是看起来被锁定了几秒钟,然后继续执行程序的其余部分(它会显示一个单独的 window 和 Wi-Fi 信息)。我尝试让线程在按钮文本更改和扫描之间休眠几秒钟,但结果是一样的。是否存在在扫描开始前文本不会更新的原因,即使扫描是在代码中的 setText 命令之后进行的?
如果有帮助,我是 运行 Qt Creator 中的 Qt 4.8.4 使用 Ubuntu。
UI 被阻塞,因为您在 UI 线程中对其调用了 waitForFinished()。为避免这种情况,您可以:
不要调用 waitForFinished(),而是连接到 QProcess 的 finished() 和 error() 信号。为此,您需要使 QProcess 成为 class 成员,以便当 Qt returns 进入事件循环时该实例仍然存在。那将是“正常的做法。
将整个 QProcess 实例化和执行移动到另一个线程中。这稍微复杂一些,只有当您有一个更复杂的控制流涉及多个相互依赖的进程时,才值得付出努力。
这绝不是一个理想的解决方案。但是,调用 QApplication::processEvents()
应该可以解决问题:
ui->toolButton->setText("Searching, please wait...");
QApplication::processEvents();
我正在编写一个程序来启用设备上的 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();
简而言之,用户按下一个按钮开始扫描,我希望按钮在扫描开始前将文本更改为 "Searching, please wait...",因为扫描需要几秒钟才能完成。
但是,UI 不会在扫描开始前更新。系统只是看起来被锁定了几秒钟,然后继续执行程序的其余部分(它会显示一个单独的 window 和 Wi-Fi 信息)。我尝试让线程在按钮文本更改和扫描之间休眠几秒钟,但结果是一样的。是否存在在扫描开始前文本不会更新的原因,即使扫描是在代码中的 setText 命令之后进行的?
如果有帮助,我是 运行 Qt Creator 中的 Qt 4.8.4 使用 Ubuntu。
UI 被阻塞,因为您在 UI 线程中对其调用了 waitForFinished()。为避免这种情况,您可以:
不要调用 waitForFinished(),而是连接到 QProcess 的 finished() 和 error() 信号。为此,您需要使 QProcess 成为 class 成员,以便当 Qt returns 进入事件循环时该实例仍然存在。那将是“正常的做法。
将整个 QProcess 实例化和执行移动到另一个线程中。这稍微复杂一些,只有当您有一个更复杂的控制流涉及多个相互依赖的进程时,才值得付出努力。
这绝不是一个理想的解决方案。但是,调用 QApplication::processEvents()
应该可以解决问题:
ui->toolButton->setText("Searching, please wait...");
QApplication::processEvents();