2014-04-07 65 views
2

在我的程序中,我打開一個窗口並運行一個大循環。我在QTextEdit中顯示進度。我添加了一個取消按鈕來停止大循環。
如何在按下按鈕後停止後臺循環?

所以在窗口的構造我跑,看起來像一個方法,

void start() 
{ 
    for (size_t i=0, i<10000000; ++i) 
    { 
     // do some computing 
     QApplication::processEvents(); // Else clicking the stop button has no effect until the end of the loop 
     if (m_stop) break; // member m_stop set to false at start. 
    } 
} 

所以,當我點擊停止按鈕,它運行插槽

void stopLoop() 
{ 
    m_stop = true; 
} 

與方法的問題是processEvents()減慢執行時間有點太多..但也許這是不可避免的..

我想嘗試它的信號和插槽s,但我似乎無法想象如何將推入的停止按鈕與循環連接起來。或者,信號和插槽與否,也許有人有一個更好的方式來實現這一目標?

編輯

繼此線程的建議,我現在有一個工人/線程場景。所以我有一個窗口的構造函數

Worker *worker; 
QThread *thread ; 
worker->moveToThread(thread); 
connect(thread, SIGNAL(started()), worker, SLOT(work())); 
connect(worker, SIGNAL(finished()), thread, SLOT(quit())); 
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater())); 
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); 
thread->start(); 

這似乎工作正常。但是我現在怎麼能介紹QTimer

如果我的QTimer連接線程的start()功能

connect(timer, &QTimer::timeout, thread, &QThread::start); 

或者,我應該螺紋連接到QTimerstart()功能?

connect(thread, SIGNAL(started()), timer, &QTimer::start()); 

或者既不... ...但是,那麼,怎麼樣?

+0

爲什麼不使用線程來完成繁重的工作? – OnWhenReady

回答

2

使用QTimer

void start() 
{ 
    this->timer = new QTimer(this); 
    connect(timer, &QTimer::timeout, this, &MyObject::work); 
    connect(stopbutton, &QButton::clicked, timer, &QTimer::stop); 
    connect(stopbutton, &QButton::clicked, timer, &QTimer::deleteLater); 
    connect(this, &MyObject::stopTimer, timer, &QTimer::deleteLater); 
    connect(this, &MyObject::stopTimer, timer, &QTimer::stop); 
    timer->setInterval(0); 
    timer->setSingleShot(false); 
    timer->start(); 

} 

void work() 
{ 
    //do some work and return 

    if (done)emit stopTimer(); 
} 
+0

看起來是這樣做的。但是有可能在線程中使用該示例嗎?看我的編輯...謝謝 – user2287453

1

一件事,你可以做的要少「塊狀」是做你的工作中使用QThread工作線程。那麼,慢下來不會是一個如此大的問題,而你仍然能夠優雅地終止工作。

我也將重新考慮這個大數目的迭代,贊成QTimer。然後,基本上取消按鈕或定時器的超時會觸發工作循環中斷。在這種情況下,迭代的時間條件是m_stop後衛。

相關問題