在非gui线程使用QMessageBox

Qt提供的MessageBox只可以在gui线程(主线程)使用,于是需要QMessageBox进行封装,可以在非gui线程内被调用。
特性:
1.可以在任何线程调用;
2.show后和默认的MessageBox一样是阻塞的,MessageBox关闭后才会返回。

  1. 使用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没有指定的父窗体,位置可能不是期望的,如果需要指定位置,则需要进行相应设置或移动。
  1. 使用线程内阻塞的信号槽连接方式实现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弹出框中的选择。
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值