在Qt應用程序開發中,我們經常會遇到這樣的問題:當執行一個耗時操作時,整個界面會卡住,無法響應任何用戶操作,甚至連一個簡單的提示彈窗都無法正常顯示。本文將介紹兩種解決這個問題的方法,并通過完整的代碼示例進行說明。
問題描述
先來看一個常見的錯誤示例:
#include <QMainWindow>
#include <QPushButton>
#include <QMessageBox>
#include <QVBoxLayout>
#include <QThread>class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr) : QMainWindow(parent){QWidget *centralWidget = new QWidget(this);setCentralWidget(centralWidget);QVBoxLayout *layout = new QVBoxLayout(centralWidget);QPushButton *button = new QPushButton("生成條碼", this);layout->addWidget(button);connect(button, &QPushButton::clicked, this, &MainWindow::onGenerateBarcodeClicked);}private slots:void onGenerateBarcodeClicked(){// 顯示提示對話框QMessageBox::information(this, "提示", "條碼生成中,請等待...");// 模擬耗時的條碼生成操作QThread::sleep(5); // 暫停5秒// 顯示完成對話框QMessageBox::information(this, "提示", "生成成功");}
};
這個代碼看起來很合理:點擊按鈕后,先顯示一個"條碼生成中"的提示框,然后執行條碼生成操作,最后顯示"生成成功"的提示。但實際運行時會發現,第一個提示框根本不會顯示,直到5秒后條碼生成完成,才會直接顯示"生成成功"的提示框。
這是因為Qt的UI是單線程的,所有UI更新都必須在主線程中進行。當執行QThread::sleep(5)
時,整個主線程被阻塞,無法處理UI事件,包括繪制和顯示對話框。因此,第一個提示框雖然被創建了,但無法在屏幕上顯示出來。
方法一:使用QCoreApplication::processEvents()
第一種解決方法是在耗時操作中定期調用QCoreApplication::processEvents()
,讓Qt有機會處理UI事件。
#include <QMainWindow>
#include <QPushButton>
#include <QMessageBox>
#include <QVBoxLayout>
#include <QThread>
#include <QProgressDialog>class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr) : QMainWindow(parent){QWidget *centralWidget = new QWidget(this);setCentralWidget(centralWidget);QVBoxLayout *layout = new