QProgressBar完成加载后不明原因的延迟 [英] unexplained delay after QProgressBar finish loading

查看:543
本文介绍了QProgressBar完成加载后不明原因的延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个循环(它进行一些计算)的触发进度条更新,它位于主GUI上,循环结束后进度条更新为100%(进度条变为隐藏,当进程结束时)的信号。 ,但是有一个延迟,进度条保持在100%,有时鼠标变为忙,并且只有几秒钟后进度条变成隐藏(表示我延迟结束),所以循环后没有什么,所以没有什么我可以想到可以使这个延迟。




  • 我应该注意,如果循环计算轻


  • 发射信号在逻辑层中的一个类中,我已经尝试了一些包括< QtGui / QApplication> 到这个类(这听起来不是正确的事情,因为这是逻辑层,为什么它应该需要QtGui库,我只是测试的东西),我把以下代码 qApp-> processEvents(); 在循环中,现在的东西似乎运行smother,没有繁忙的鼠标,仍然有一个延迟(唯一不同的是,我可以与GUI反应,而这种延迟发生,但没有更新的结果,直到这个延迟结束)。



    测试用 processEvents()我认为它是与线程相关的东西,但如果是如此,如何纠正延迟行为,当然如果任何人认为它可以是东西



    一些示例代码:



    逻辑图层类:

      #include< QtGui / QApplication> 
    ...

    processMethod(...)
    {
    Loop(...)
    {
    qApp-> processEvents ();
    emit processBarSignle(value);
    ...一些计算...
    }
    emit processBarSignle(100);
    }

    查看图层(MainWindow):

      on_btn_nextProcess_clicked()
    {
    m_ui-> pBar_process-> setVisible(true);
    LogicClass-> processMethod(...);
    m_ui-> pBar_process-> setVisible(false);
    }

    感谢

    解决方案

    在你的代码示例中,实际上只有一个线程。当调用 on_btn_nextProcess_clicked()时,它显示进度条,然后在同一个线程中运行 processMethod()。理想情况下,您希望分离您的UI和数据处理逻辑。



    在初始化中,创建一个单独的 QThread ,并通过调用logicClassObject-> moveToThread([你的新线程])将您的LogicClass对象移动到该线程。然后,将 processMethod()插入一个插槽,在MainWindow中创建一个 startProcessing()最后,在 MainWindow finishedProcessing() processingDone() c $ c>插入 LogicClass 并连接它们。当这一切都设置完成后,您可以更改您的代码如下:

      void LogicClass :: processMethod b $ b {
    Loop(...)
    {
    emit processBarSignal(value);
    ...一些计算...
    }
    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);
    }

    每当你从两个不同的线程连接信号和插槽时,多线程处理自动。在一个线程中发出信号导致在另一个线程中调用事件,只有在第二线程重新获得控制时才调用该槽。



    在这种情况下,UI线程将在处理线程中调度一个事件以开始处理。然后,处理线程将继续调度progressBar值更新,最后调度一个事件以在完成时关闭进度条。这两个线程将根据操作系统线程调度程序运行,并且处理不会阻止UI。


    I have emit signal from a loop (which make some calculations) that triggers progress bar update which located on the main GUI, after the loop ends the progress bar updated to 100% (the progress bar become hidden when the process ends), but than there is a delay, the progress bar stays on 100% and sometimes the mouse changes to busy, and only after few seconds the progress bar become hidden (indicates me that the delay ends), there is nothing after that loop, so nothing I can thinks of can make this delay.

    • I should note that if the loop calculations are light (meaning not a lots of calculations need to be done) there is no such delay.

    The emit signal is inside a class in the logic layer, I have try something by including <QtGui/QApplication> into that class (which sounds to me not the right thing to do, as this is the logic layer so why it should need QtGui libraries, but I'm only testing something), I put the following code qApp->processEvents(); inside the loop and now things seems to run smother, no busy mouse, but still there is a delay (the only thing different I can react with the GUI while this delay occurs, but there is no updated results until this delay ends).

    Because of the test with the processEvents() I was thinking it's something related to threads, but if so how can I correct the delay behavior, of-course if anyone thinks it could be something else, please do tell.

    Some sample code:

    Logic layer class:

    #include <QtGui/QApplication>
    ...
    
    processMethod(...)
    {
        Loop(...)
        {
            qApp->processEvents();
            emit processBarSignle(value);
            ...some calculations...
        }
        emit processBarSignle(100);
    }
    

    View layer (MainWindow):

    on_btn_nextProcess_clicked()
    {
        m_ui->pBar_process->setVisible(true);
        LogicClass->processMethod(...);
        m_ui->pBar_process->setVisible(false);
    }
    

    Thanks

    解决方案

    In your code sample, there is actually only one thread. When on_btn_nextProcess_clicked() is called, it shows the progress bar, then runs processMethod() in the same thread. Ideally you want to separate your UI and Data Processing logic.

    In intialization, create a separate QThread, start it, and move your LogicClass object to that thread by calling logicClassObject->moveToThread([your new thread]). Then, turn processMethod() into a slot, create a startProcessing() signal in MainWindow and connect the two. Finally, create a processingDone() slot in MainWindow and a finishedProcessing() slot in LogicClass and connect them. When this is all set up you can change your code to the following:

    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);
    }
    

    Whenever you connect signals and slots from two separate threads, multithreading is taken care of automatically. Emitting the signal in one thread causes an event to be qeued in the other which only calls the slot once the second thread regains control.

    In this case, the UI thread will schedule an event in the processing thread to start processing. The processing thread will then continually schedule progressBar value updates and finally schedule an event to turn off the progress bar when its done. The two threads will run according to the OS thread scheduler and processing won't block UI.

    这篇关于QProgressBar完成加载后不明原因的延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆