2016-01-18 50 views
0

我第一次使用QT,並添加元素時刷新GUI的一些問題。QT添加項目觸發器重畫,而不是凍結

代碼如下:

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 

    PObj obj; 
    MainWindow mw; 
    qRegisterMetaType<std::string>(); 

    QObject::connect(&obj, SIGNAL(setText(std::string const&)), 
        &mw, SLOT(appendText(std::string const&))); 

    QFuture<void> f1 = QtConcurrent::run(&obj, &PObj::process); 
    mw.show(); 

    f1.waitForFinished(); 

    return a.exec(); 
} 

隨着PObj ::流程定義:

void PObj::process() 
{ 
for(; ;) 
{ 
    sleep(1); 

    //do work and set text 
    std::string text = "bla"; 
    emit setText(text); 
} 
} 

而且主窗口:: AppendText通過插槽:

void MainWindow::appendText(std::string const& str) 
{ 
    ui->listWidget->addItem(QString::fromStdString(str)); 
} 

我試着放置qApp-> processEvents(),QCoreApplication :: processEvents(); ...在ThreadPool中運行智能未來。

我以爲用Concurrent :: run運行它們就足夠了嗎?

UPDATE:

是,爲什麼第二一個新項目添加問題心不是刷新一次,圖形用戶界面?

+0

@hyde,你是對的我編輯問題 – Roby

回答

0

f1.waitForFinished();調用塊,直到f1完成,顧名思義。這永遠不會發生,因爲你有無限循環。所以你的代碼永遠不會進入主循環。你不能阻止這樣的主線程!一般來說,避免任何WaitForXxxx()方法,特別是GUI線程。

此外,您無法停止process();無論如何,等待它完成沒有任何意義...您可能想要添加一種方法來告訴它停止(如原子變量),但無論如何,要解決您的問題,只需刪除f1.waitForFinished();行。

很好地終止任務,嘗試添加QAtomicInt標誌(揮發性布爾值,它不會做),然後更改這樣的代碼:

成員變量添加到PObj(應該讓私人並添加二傳手):

QAtomicInt termianteFlag; 

變化主要是這樣的:

int main(int argc, char *argv[]) 
{ 
    ///snip 

    QFuture<void> f1 = QtConcurrent::run(&obj, &PObj::process); 
    mw.show(); 

    int ret = a.exec(); 
    f1.terminateFlag = 1; // change this to setter method 
    f1.waitForFinished(); // this is not ideal, will wait for up to a second before exit 

} 

void PObj::process() 
{ 
    while(!terminateFlag) 
    { 
     sleep(1); 

     //do work and set text 
     std::string text = "bla"; 
     emit setText(text); 
    } 
}