我已经从一个循环(这使一些计算)触发,其位于主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 ,像就足够了仅包括QCoreApplication
其是一部分QtCore
库。
此外,你应该添加processEvents()
之前没有进度栏已经更新后,。
需要注意的是processEvents()
不会返回,直到在Qt的事件队列中的每个事件已被处理。 如果如Cancel
按钮,你将不得不检查,如果用户每次调用时实际上取消了操作processEvents()
您可以排除用户特定的事件,如鼠标点击/通过使用按键
QCoreApplication::processEvents( QEventLoop::ExcludeUserInputEvents )
但不会允许任何点击(如取消按钮),而循环是有效的。
作为再一注:这应该叫“processBarSi 纳克乐” ;-)
澄清主题等:
你的整个循环,任何鼠标点击等只在一个线程中执行。 如果调用emit()
所述slot
被连接到该signal
立即被执行( 除非狭槽实际上是在不同的线程 )。 在此期间,循环不下去!
当插槽已经完成,你的循环将持续下去。 在我的例子,这意味着processEvents()
将被调用。 现在,如果你的插槽更新进度条或做其他任何这引起了重绘,会有事件队列中的重绘事件,这重绘现在会发生。
如果执行processEvents()
调用您的插槽前,将有可能在这一点上没有处理重绘事件。
再次,循环就不会继续下去,直到processEvents()
是完全做得到。 当所有未决事件进行了处理,循环将继续与你的计算。
在您的代码示例,但是实际上只有一个线程。 当on_btn_nextProcess_clicked()
被调用时,它显示进度条,然后运行processMethod()
在同一个线程。 理想情况下,你要分开你的用户界面和数据处理逻辑。
在intialization,创建一个单独QThread
,启动它,并通过调用logicClassObject-> moveToThread移动你的LogicClass对象线程([你的新线索])。 然后,打开processMethod()
插入插槽中,创建一个startProcessing()
在主窗口信号和连接两个。 最后,创建一个processingDone()
插槽MainWindow
和finishedProcessing()
插槽LogicClass
和连接它们。 当这一切设置你可以改变你的代码如下:
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线程将在处理线程安排一个事件开始处理。 然后,处理线程将继续安排进度值更新,并最终安排一个事件的完成后关闭进度条。 两个线程将根据OS线程调度器运行,并且处理将不会阻止UI。