Qt 如何處理密集型耗時的事情(頻繁調用QApplication::processEvents)


     有時候需要處理一些跟界面無關的但非常耗時的事情,這些事情跟界面在同一個線程中,由於時間太長,導致界面無法響應,處於“假死”狀態。例如:在應用程序中保存文件到硬盤上,從開始保存直到文件保存完畢,程序不響應用戶的任何操作,窗口也不會重新繪制,從而處於“無法響應”狀態,這是一個非常糟糕的體驗 。

     在這種情況下,有一種方法是使用多線程,即在子線程中處理文件保存,主線程負責界面相關。

     而如果不想使用多線程,最簡單的辦法就是在文件保存過程中頻繁調用QApplication::processEvents()。該函數的作用是讓程序處理那些還沒有處理的事件,然后再把使用權返回給調用者。

代碼如下:

復制代碼
bool MyApp::writeFile(const QString &filename)
{
     QFile file(filename);
...
    QApplication::setOverrideCursor(Qt::WaitCursor);
     for(int r = 0; r != rowCount; ++r)
     {
          for(int c = 0; c != colCount; ++c)
          {
               out << table(r,c);   
               qApp.processEvents();
          }
     }
    QApplication::restoreOverrideCursor();
}
復制代碼

     這樣一來,程序就能響應了。

     但是,該方法有一個問題:可能正在保存文件的過程中,用戶不小心又單擊了保存,或不小心關閉了程序主窗口,這樣會產生意想不到的后果。

     解決這個問題的最簡單的辦法是替換成:

qApp->processEvents(QEventLoop::ExcludeUserInputEvents);//它可以忽略用戶的輸入(鼠標和鍵盤事件)。

 

     進一步的,如果想顯示一個帶有進度條的對話框,隨時顯示當前的進度狀態,可以使用QProgressDialog。

復制代碼
bool MyApp::writeFile(const QString &filename)
{
     QFile file(filename);
...
    QApplication::setOverrideCursor(Qt::WaitCursor);
     QProgressDialog progress;
     progress.setWindowTitle(tableData->sNameCH);
     progress.setLabelText(QStringLiteral("數據保存中,請稍候..."));
     //progress.setCancelButton(0);//不顯示“取消”按鈕
     progress.setCancelButtonText("取消");
     progress.setRange(0,rowCount );
     progress.setModal(true);
     //此處沒有調用show()來顯示,是因為QProgressDialog會自動決定是否顯示
     //如果時間過短,就不會顯示。
     for(int r = 0; r != rowCount; ++r)
     {
          progress.setValue(row);
          //如果用戶單擊了“取消”,就取消保存文件,並刪除該文件。
          if(progress.wasCanceled)
          {
               file.remov();
               return false;
          }
          for(int c = 0; c != colCount; ++c)
          {
               out << table(r,c);   
               qApp.processEvents();
          }
     }
    QApplication::restoreOverrideCursor();
}
復制代碼

顯示效果如下:

ScreenClip

http://www.cnblogs.com/xiongxuanwen/p/5431027.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM