为了使按钮更改状态,它需要返回到事件循环中的处理事件。
为了解决这个问题,你可以在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