Qt控件点击消息获取
中国好公民st 人气:0今日为大家分享一个小功能实现:如何获取控件点击响应。
在这里,我以两个最简单并且具有代表性的控件来进行功能讲解。
举例控件:QLabel、QPushButton
对于这两个控件大家应该都不会陌生了,做界面开发经常会用到的。
开发环境:VS2017 + Qt5.14.2
首先来讲如何获取点击控件响应,QPushButton自身就带有了clicked消息,直接实现响应消息就可以了。
除此之外,还有其他方式可以响应该控件吗?对此,我将QPushButton响应鼠标按下的消息做一个整理。
1.QPushButton响应鼠标点击消息
1.1自身响应消息clicked
最简单的莫过于QPushButton自身的clicked消息。
创建响应槽函数
connect(ui.btn1, QPushButton::clicked, this, &QMyWidget::OnBnClicked1);
实现按钮响应消息
void QMyWidget::OnBnClicekd1() { //响应控件,做具体的响应消息处理 }
1.2事件过滤器响应消息
在Qbject中有这么一个函数:eventFilter
建立事件过滤器。
virtual bool eventFilter(QObject * watched, QEvent * event)override;
想要获取哪个控件的消息只需要监视该控件就可以了。
控件监视:ui.btn1->installEventFilter(this);
对该控件实施监视后,该如何处理呢?
首先,需要判断操作对象是否为QPushButton控件?除此之外全部过滤掉
if(watched == ui.btn1) { //是QPushButton过滤事件 } else { //不是QPushButton事件,忽略处理 }
其次,截获出鼠标按下消息
if(event->type() == QEvent::MouseButtonPress) { //鼠标按下消息 }
到这里,为了验证正确性,可以用输出日志的方式。发现,果然可以响应按钮控件响应。
但是,还有一些小瑕疵,测试发现,无论是左键点击鼠标、右键点击鼠标或者是双击鼠标,都会触发该消息,这就需要我们做进一步优化了。
最后,筛选左键响应消息
接收到鼠标按下消息后,此刻可以将事件转化成鼠标事件,更进一步判断。
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); if (mouseEvent->button() & Qt::LeftButton) { QPoint pt = mouseEvent->pos(); qDebug() << QStringLiteral("<eventFilter>事件中,点击鼠标左键的位置 = ") << pt; }
写到这里,在尝试下发现鼠标右键点击消息不会触发了。
但是,还存在一个小问题,当鼠标左键双击按钮时,依旧响应该消息。这里,就需要对QPushButton做一下特殊处理了,我们后续再进行详细讲解。
到这里,使用事件过滤器eventFilter处理按钮响应就算完成了。
1.3mousePressEvent事件获取
使用mousePressEvent事件可以获取到按钮的响应消息吗?
答案是不可以的。
如果想要验证真理的小伙伴可以在mousePressEvent中输出日志,会发现,当点击按钮控件时,是不会触发该消息的,只有在控件之外或者是静态控件上才会响应。
所以,使用mousePressEvent方法获取是不可取的。
综上所述,想要获取具有响应消息的控件(例如:QPushButton)点击事件方法只有前两种方式是可取的。
2.QLabel响应鼠标点击消息
QLabel控件也可以说是静态显示控件,查看底层类可以发现,该类不具备鼠标响应事件,那么对于这种控件该如何获取点击事件呢?
2.1事件过滤器响应消息
与按钮响应事件获取方法一致,通过监视控件,截获消息的方式实现,这里就不再过多说明了。
2.2mousePressEvent事件获取
QPushButton控件使用鼠标按下响应无法获取消息,但是QLabel是可以的。
那么该如何获取呢?
核心:获取mousePressEvent中点的位置,将其转换成控件位置,是否存在有效控件指针
QLabel *child = static_cast<QLabel*>(childAt(event->pos())); if (child) { //鼠标点击在QLabel控件上 } else { //鼠标未点击在控件上,忽略处理 }
到此,两种具有代表性的控件响应消息获取方式已经讲解完成了,是不是很简单?
加载全部内容