Qt 信号与槽总结

本文探讨了在Qt项目中,底层子线程如何通过信号向主界面发送警告消息,遇到的bool类型连接问题,以及如何通过qRegisterMetaType解决。重点介绍了Qt的DirectConnection和信号类型转换技巧。

最近写项目时候,碰到一个功能需求。底层类子线程循环运行时,碰到问题可以让主界面随时弹警告框。

于是写了个信号,由底向主界面类发送信号,主界面实现槽函数功能即可。写的信号如下:

void signalPopupMessageBox(QMessageBox::StandardButton &resultBtn, const QString &title, const QString &text,
        QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);

bool PopUpMsg(QString txt,bool bNeedReturn /*= true*/)
{
	QString title = QString::fromLocal8Bit("提示");
	QMessageBox::StandardButtons btns = QMessageBox::Yes | QMessageBox::No;
	QMessageBox::StandardButton btnDefault = QMessageBox::No;
	QMessageBox::StandardButton btnRet = QMessageBox::No;
	bool bRet = false;  //是否已经获得结果
	emit signalPopupMessageBox(btnRet, title, txt, bRet,btns, btnDefault);

	if (!bNeedReturn)
	{
		return true;
	}

	do 
	{
		Sleep(10);
	} while (!bRet);

	if (QMessageBox::Yes == btnRet)
	{
		return true;
	}
	else
	{
		return false;
	}
}

一般Qt会默认选择Qt:AutoConnection,并且信号与槽位于同一线程,那么QT会自动为我们选择为Qt::DirectConnection方式。Qt里DirectConnection解释为 :发出信号时立即调用插槽。 插槽在信号线程中执行。相当于槽函数直接执行,执行完之后,才继续执行信号的后续内容。也就是说 上述 signalPopupMessageBox信号发送后,会一直等待槽函数执行完成,才会执行后面的操作。

另外,如果我把这个函数放在子线程中,由子线程往主界面线程发送信号,碰到的问题为:QObject::connect: Cannot queue arguments of type ‘StandardButton &’。在建立连接之前,请调用qRegisterMetaType()注册数据类型。信号发送失败了。

以前做项目时,也碰到过这个问题。信号发送的内容为自定义的枚举类,导致一直发送不成功。

类的头文件里声明;
enum DEVICESTATION_ID
{
	DEVICESTATION_S1 =1,
	DEVICESTATION_S2,
	DEVICESTATION_S3,
	DEVICESTATION_S4,
	DEVICESTATION_NUM = DEVICESTATION_S4,
};

Q_ENUMS(DEVICESTATION_ID)

类的构造函数里添加:
qRegisterMetaType<DEVICESTATION_ID>("DEVICESTATION_ID");

这样可以解决信号发送失败的问题。信号发送的时候一定要发送Qt能识别的类型。

后来把信号改成void signalPopUpMsgBox(QString title,QString text,bool &bFinish,bool &bRet);

运行时,还是提示bool& 类型有问题,最终改成指针方式了。

void signalPopUpMsgBox(QString title,QString text,bool *bFinish,bool *bRet);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值