Qt提供的MessageBox只可以在gui線程(主線程)使用,於是需要QMessageBox進行封裝,可以在非gui線程內被調用。
特性:
1.可以在任何線程調用;
2.show後和默認的MessageBox一樣是阻塞的,MessageBox關閉後纔會返回。
- 使用moveToThread將QMessageBox實際調用移動到主線程中,並使用QEventLoop實現阻塞。
聲明
#include <QMessageBox> #include <QEventLoop> class ThreadInformationMessageBox : public QObject { Q_OBJECT private: const QString m_strTitle; const QString m_strMessage; public: ThreadInformationMessageBox(const QString &strTitle, const QString &strMessage); static void show(const QString &strTitle, const QString &strMessage); private: void readyShow(void); private slots: void onShow(void); };
實現
ThreadInformationMessageBox::ThreadInformationMessageBox(const QString &strTitle, const QString &strMessage) : m_strTitle(strTitle), m_strMessage(strMessage) { } void ThreadInformationMessageBox::show(const QString &strTitle, const QString &strMessage) { QEventLoop eventLoop; auto messageBox = new ThreadInformationMessageBox(strTitle, strMessage); connect(messageBox, SIGNAL(destroyed()), &eventLoop, SLOT(quit())); messageBox->readyShow(); eventLoop.exec(); } void ThreadInformationMessageBox::readyShow(void) { this->moveToThread(qApp->thread()); QTimer::singleShot(0, this, SLOT(onShow())); } void ThreadInformationMessageBox::onShow(void) { QMessageBox::information(NULL, m_strTitle, m_strMessage); this->deleteLater(); }
使用
ThreadInformationMessageBox::show("Title", "Message");
備註
該QMessageBox沒有指定的父窗體,位置可能不是期望的,如果需要指定位置,則需要進行相應設置或移動。
- 使用線程內阻塞的信號槽連接方式實現QMessageBox。
代碼
Q_SIGNALS: int SendMessageSignal(const QString& title, const QString& content, QMessageBox::Icon icon, const QString& button0Text, const QString& button1Text = QString(), const QString& button2Text = QString()); // 連接線程內的信號與匿名函數 connect(pObjectHasThread, &ObjectHasThread::SendMessageSignal, this, [=]( const QString& title, const QString& content, QMessageBox::Icon icon, const QString& button0Text, const QString& button1Text = QString(), const QString& button2Text = QString()) -> int { switch (icon) { case QMessageBox::Information: return QMessageBox::information(this, title, content, button0Text, button1Text, button2Text); break; case QMessageBox::Warning: return QMessageBox::warning(this, title, content, button0Text, button1Text, button2Text); break; case QMessageBox::Question: return QMessageBox::question(this, title, content, button0Text, button1Text, button2Text); break; case QMessageBox::Critical: return QMessageBox::critical(this, title, content, button0Text, button1Text, button2Text); break; default: return -1; } }, Qt::BlockingQueuedConnection);
備註
1. pObjectHasThread爲自定義線程對象或含有線程操作的對象,需要在此線程操作中使用QMessageBox; 2. 使用時直接在pObjectHasThread對象中發射SendMessageSignal即可; 3. Qt::BlockingQueuedConnection連接方式實現了線程內阻塞,該種連接方式僅適用於信號和槽函數在不同線程中的情形; 4. int爲匿名函數的返回值,即用戶在QMessageBox彈出框中的選擇。