(爬坑实录)解决QPushbutton 点击弹出popup后,从hover状态恢复到普通状态的问题

和这篇文章遇到的问题极其相似
解决Qt qpushbutton stylesheet hover
但是按照这篇文章的解决方法并不能解决我的问题,我是按照自己的方法解决的。

一、问题描述:
用qss设置了鼠标的几种状态,分别是正常状态、hover状态和pressed状态。
点击按钮后,在按钮下方弹出一个自定义的Widget,这个继承自widget类的构造函数中设置了窗口的属性

setWindowFlags(Qt::Popup | Qt::FrameLessWindowHint)

问题出现了,点击这个按钮后,弹出一个自定义的pop窗口,但是这时候按钮还是hover状态。
鼠标从这个按钮上移走也没有状态变化,只能先让pop窗口消失后,再将鼠标移动到刚才那个按钮,再移开,才会看到按钮恢复到正常状态。

二、分析原因
为了便于描述,刚才那个肇事按钮就以settingPushButton称了。
原因是点击settingPushButton后,鼠标还在settingPushButton上,这时候一个popup窗口出来了,是个模态框(点击其他地方这个popup窗口才会消失),事件循环在popup中,settingPushButton自然就无法收到移出事件了。

三、解决
在按钮的槽函数,也就是刚才那个弹出popup之前

ui->settingPushButton->setAttribute(Qt::WA_UnderMouse, fasle);
QHoverEvent hoverEvent(QEvent::HoverLeave, QPoint(40, 40), QPoint(0, 0));
QCoreApplication::sendEvent(ui->settingPushButton, &hoverEvent);

注意添加相应的头文件

四、讲解
Qt::WA_UnderMouse表示
Indicates that the widget is under the mouse cursor.
就是这个是表示widget在鼠标下方

ui->settingPushButton->setAttribute(Qt::WA_UnderMouse, fasle);

是先让ui->settingPushButton以为自己不在鼠标的下方。
然后手动构造一个鼠标移走的事件

QHoverEvent hoverEvent(QEvent::HoverLeave, QPoint(40, 40), QPoint(0, 0));
QCoreApplication::sendEvent(ui->settingPushButton, &hoverEvent);

函数讲解

QHoverEvent::QHoverEvent(QEvent::Type type, const QPointF &pos, 
						const QPointF &oldPos, Qt::KeyboardModifiers modifiers = Qt::NoModifier)

QEvent::Type是事件类型,这里的事件类型只能是三种中的一个:QEvent::HoverEnter, QEvent::HoverLeave, or QEvent::HoverMove.

pos表示移动后的坐标点,是相对坐标,是相对于接收该事件的widget的坐标
oldPos表示移动前的坐标点,也是相对坐标,是相对于接收该事件的widget的坐标

oldPos的坐标为QPoint(0, 0)就可以了。

我的按钮大小只有20*20大小
移动后的坐标设置成QPoint(40, 40),在按钮的范围外就行。

最后一个参数保存默认值就行。

QCoreApplication::sendEvent中的事件是在栈上创建的,因为我这个的槽函数是同一个线程,UI线程,所以不存在跨线程的问题。在栈上构造一个QHoverEvent事件,传递给ui->settingPushButton,问题解决。

参考:解决Qt qpushbutton stylesheet hover

  • 17
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值