QProgressBar 完成加载后无法解释的延迟
unexplained delay after QProgressBar finish loading
我从一个循环(进行一些计算(发出信号,触发位于主GUI上的进度条更新,循环结束后进度条更新为100%(进程结束时进度条变为隐藏(,但比有延迟,进度条保持在100%,有时鼠标变为忙碌, 并且仅在几秒钟后进度条被隐藏(指示我延迟结束(,该循环之后没有任何内容,因此我无法想到任何内容都可以使此延迟。
- 我应该注意,如果循环计算很轻(意味着不需要做很多计算(,则没有这样的延迟。
发射信号在逻辑层的一个类内,我已经尝试了一些东西,将<QtGui/QApplication>
包含在该类中(这对我来说听起来不是正确的做法,因为这是逻辑层,所以为什么它应该需要 QtGui 库,但我只是在测试一些东西(,我将以下代码qApp->processEvents();
放在循环中,现在事情似乎窒息了, 没有繁忙的鼠标,但仍然存在延迟(唯一不同的是,当这种延迟发生时,我可以对 GUI 做出反应,但在此延迟结束之前没有更新的结果(。
由于对processEvents()
的测试,我认为这与线程有关,但如果是这样,我该如何纠正延迟行为,当然,如果有人认为这可能是其他东西,请告诉。
一些示例代码:
逻辑层类:
#include <QtGui/QApplication>
...
processMethod(...)
{
Loop(...)
{
qApp->processEvents();
emit processBarSignle(value);
...some calculations...
}
emit processBarSignle(100);
}
视图层(主窗口(:
on_btn_nextProcess_clicked()
{
m_ui->pBar_process->setVisible(true);
LogicClass->processMethod(...);
m_ui->pBar_process->setVisible(false);
}
谢谢
尝试以下操作:
#include <QtCore/QCoreApplication>
...
processMethod(...)
{
Loop(...)
{
emit processBarSignle(value);
QCoreApplication::processEvents();
...some calculations...
}
emit processBarSignle(100);
QCoreApplication::processEvents();
}
processEvents()
是QCoreApplication的一种静态方法,就像它只包含QtCore
库中的QCoreApplication
就足够了。
此外,您应该在进度条更新后添加processEvents()
,而不是在此之前。
请注意,在处理完Qt事件队列中的每个事件之前,processEvents()
不会返回。例如,如果有Cancel
按钮,则必须检查用户是否在每次调用 .
时实际取消了操作processEvents()
您可以使用以下命令排除用户特定的事件,例如鼠标单击/按键
QCoreApplication::processEvents( QEventLoop::ExcludeUserInputEvents )
但这不允许在循环处于活动状态时单击任何内容(例如取消按钮(。
作为进一步的说明:它应该被称为"processBarSi ng le";-(
关于线程等的说明:
您的整个循环以及任何鼠标点击等仅在一个线程中执行。如果您调用 emit()
,连接到该signal
的slot
会立即执行(除非该插槽实际上在不同的线程中(。同时,循环不会继续!
插槽完成后,循环将继续。在我的示例中,这意味着processEvents()
将被调用。现在,如果您的插槽更新了进度条或执行了导致重绘的任何其他操作,则事件队列中将出现重绘事件,并且此重绘现在将发生.
如果在调用槽之前执行processEvents()
,则此时不会有可以处理的重绘事件。
同样,循环不会继续,直到processEvents()
完全完成。处理完所有挂起事件后,循环将继续计算。
在代码示例中,实际上只有一个线程。 调用 on_btn_nextProcess_clicked()
时,它会显示进度条,然后在同一线程中运行processMethod()
。 理想情况下,您希望将 UI 和数据处理逻辑分开。
在初始化中,创建一个单独的QThread
,启动它,并通过调用 logicClassObject->moveToThread([您的新线程](将 LogicClass 对象移动到该线程。 然后,将processMethod()
变成插槽,在 MainWindow 中创建startProcessing()
信号并将两者连接起来。 最后,在MainWindow
中创建一个processingDone()
插槽,在LogicClass
中创建一个finishedProcessing()
插槽并连接它们。完成所有设置后,您可以将代码更改为以下内容:
void LogicClass::processMethod(...)
{
Loop(...)
{
emit processBarSignal(value);
...some calculations...
}
emit processingDone();
}
void MainWindow::on_btn_nextProcess_clicked()
{
m_ui->pBar_process->setVisible(true);
emit startProcessing(...);
}
void MainWindow::finishedProcessing()
{
m_ui->pBar_process->setVisible(false);
}
每当您连接来自两个独立线程的信号和插槽时,都会自动处理多线程。 在一个线程中发出信号会导致另一个线程中的事件被 qeued,该事件仅在第二个线程重新获得控制权时才调用该插槽。
在这种情况下,UI 线程将在处理线程中计划一个事件以开始处理。 然后,处理线程将不断计划进度栏值更新,并最终计划一个事件以在完成后关闭进度栏。 这两个线程将根据操作系统线程计划程序运行,并且处理不会阻止 UI。
- 无法解释以下C++代码段的输出
- 数组中无法解释的最后一个项目
- 对于相同的精确计算,无法解释的不同OMP_GET_WTIME()
- C 常量无法解释的行为
- C 无法解释的类“尚未声明”错误,这是由于名称空间而导致的
- [C++]重新定义 y 值的基本数组代码。它正在工作,但无法解释为什么
- std::future::wait 是内存障碍吗?(我无法解释这种数据竞赛)
- unsigned int/signed int/long-long:无法解释的输出
- C++:带有cout和指向char的指针的无法解释的行为
- 我的C++片段中无法解释的断言失败
- C 构造函数中无法解释的调用
- Excel VBA中C++DLL位置存在无法解释的行为
- 无法解释的 VIM 或 GCC 行为
- Marshal.StructureToPtr出现无法解释的内存泄漏
- 为什么这个自定义比较器在构造 std::p riority_queue 时无法解释 std::sort
- QT应用程序无法解释使用SQLite插入功能
- 无法解释的链接器错误
- 无法解释编译器的行为
- C时间混合问题似乎无法解释,以及如何明智地升级代码库
- QProgressBar 完成加载后无法解释的延迟