爲了使按鈕更改狀態,它需要返回到事件循環中的處理事件。
爲了解決這個問題,你可以在while循環之前調用QApplication::processEvents,儘管在啓動長時間函數之前,通過調用函數作爲QueuedConnection自然返回到事件循環會更好。
或者,更好的方法是在一個單獨的線程通過創建一個對象來封裝功能來運行的功能,這將使您的GUI中的「長函數」
開始的處理過程中保持活性這將做的工作: -
class Worker : public QObject {
Q_OBJECT
public:
Worker();
~Worker();
public slots:
void process(); // This is where your long function will process
signals:
void finished();
void error(QString err);
};
void Worker::process()
{
while(x<1000000) x++; //e.g of my long time function
emit finished();
}
創建一個新的線程,並啓動按鈕被點擊
void MainWindow::on_pushButton_clicked()
{
// change button visibility
ui->progressBar->setVisible(true);
ui->pushButton->setVisible(false);
// create the new thread and start the long function
QThread* thread = new QThread;
Worker* worker = new Worker();
worker->moveToThread(thread);
connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
connect(thread, SIGNAL(started()), worker, SLOT(process()));
//ensure the objects are cleared up when the work is done
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
//start the thread and the long function processing
thread->start();
}
創建一個全新的類,所有的鍋爐都是矯枉過正的。將長期運行的代碼分離成一個私有函數並獲得'QtConcurrent'來完成所有線程設置和執行會更好。 – RobbieE 2014-08-29 05:53:17
@RobbieE是的,這是很多代碼,但我會避免QtConcurrent:http://comments.gmane.org/gmane.comp.lib.qt.devel/7942 – TheDarkKnight 2014-08-29 07:42:26