非常抱歉,是我疏忽了。在上面的例子中确实没有使用QCoreApplication::processEvents()
。以下是一个更新后的示例,演示如何在等待worker线程完成之前处理GUI事件:
#include <QtWidgets>
#include <QtCore>
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = nullptr) : QObject(parent) {}
signals:
void resultReady(const QString &result);
public slots:
void doWork()
{
// Do some heavy work here...
QThread::sleep(3);
QString result = "Hello World from worker thread!";
emit resultReady(result);
}
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr) : QMainWindow(parent)
{
setCentralWidget(new QLabel("Click the button to start processing..."));
QPushButton *button = new QPushButton("Start Processing", this);
connect(button, &QPushButton::clicked, this, &MainWindow::startProcessing);
}
private slots:
void startProcessing()
{
// Disable UI controls and show progress bar.
centralWidget()->setEnabled(false);
m_progressBar = new QProgressBar(this);
statusBar()->addWidget(m_progressBar);
// Create worker object and move it to a separate thread.
m_workerThread = new QThread(this);
Worker *worker = new Worker();
connect(worker, &Worker::resultReady, this, &MainWindow::handleResult);
// Move worker to a separate thread and start it.
worker->moveToThread(m_workerThread);
connect(m_workerThread, &QThread::started, worker, &Worker::doWork);
connect(worker, &Worker::resultReady, m_workerThread, &QThread::quit);
// Wait for the worker thread to finish before cleaning up.
connect(m_workerThread, &QThread::finished, [this]() {
m_workerThread->deleteLater();
m_progressBar->deleteLater();
centralWidget()->setEnabled(true);
});
// Start the worker thread and show progress bar.
m_progressBar->setRange(0, 0);
m_workerThread->start();
// Process events until the worker thread finishes.
while (m_workerThread->isRunning()) {
qApp->processEvents();
QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
}
}
void handleResult(const QString &result)
{
// Update UI with the result from worker thread.
QLabel *label = new QLabel(result, this);
setCentralWidget(label);
}
private:
QThread *m_workerThread;
QProgressBar *m_progressBar;
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
#include "main.moc"
在上面的示例中,我们将QCoreApplication::processEvents()
函数添加到了启动worker线程之后的循环中。这将确保事件循环能够响应GUI事件,并且在等待worker线程完成时不会阻塞。
注意,我们还使用了QCoreApplication::sendPostedEvents()
函数来删除所有延迟删除事件,以避免资源泄漏。