好吧,事件分配是我自己给它起的名字.
当事件对象创建完毕后并不是立即被执行了,QT会将这个事件对象传递给首先传递给QObject的event()函数,
event()函数并不直接处理事件而是按照事件的类型来分配给不同的事件处理器.(比如:mousePressEvent(QMouseEvent* ev)).如果该函数返回true那么表明该事件已经被处理过了.对于其他我们不关心的事件,我们则是直接调用父类的event()函数再次进行分配.
如标题所说,event()就是用来分发事件的,因此如果希望在事件分发之前做一些事情那么就需要重写子类中的该函数.
说了那么多来让我们看个例子吧:
#include <QWidget>
#include <QEvent>
#include <QKeyEvent>
#include <QDebug>
class CustomWidget : public QWidget
{
Q_OBJECT
public:
CustomWidget(QWidget* parent = nullptr);
~CustomWidget()=default;
virtual bool event(QEvent* ev)override;
protected:
virtual void mousePressEvent(QMouseEvent* ev)override;
virtual void keyPressEvent(QKeyEvent* ev)override;
private slots:
//void onClicked()const noexcept;
};
#include "mainwindow.h"
CustomWidget::CustomWidget(QWidget* parent)
:QWidget(parent)
{
this->setMinimumSize(500, 400);
}
bool CustomWidget::event(QEvent* ev)
{
if(ev->type() == QEvent::MouseButtonPress){
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(ev);
if(mouseEvent->buttons() == Qt::LeftButton){
qDebug()<<"You press LeftButton by Mouse";
return true; //返回true表明该事件已经被识别且已经被处理了.
}
}
return this->QWidget::event(ev); //如果没被处理那么交给基类分配.
}
void CustomWidget::mousePressEvent(QMouseEvent* ev)
{
qDebug()<<"mouse pressed!";
}
void CustomWidget::keyPressEvent(QKeyEvent* ev)
{
qDebug()<<"key pressed!";
}
当我们点击CustomWidget的时候显示的是:
You press LeftButton by Mouse
你没有看错!mousePressEvent()没有被调用!!!
那我们来修改一下吧:
bool CustomWidget::event(QEvent* ev)
{
if(ev->type() == QEvent::MouseButtonPress){
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(ev);
if(mouseEvent->buttons() == Qt::LeftButton){
qDebug()<<"You press LeftButton by Mouse";
this->mousePressEvent(mouseEvent); //注意这里!!!!!!!!!!!!!!
return true; //返回true表明该事件已经被识别且已经被处理了.
}
}
return this->QWidget::event(ev); //如果没被处理那么交给基类分配.
}
我们在其中加入了mousePressEvent()函数再看运行后的结果:
You press LeftButton by Mouse
mouse pressed!
正常了!!!!!!!!!!!!
我们来看一下QObject中event()的实现吧:
//!!! Qt5
bool QObject::event(QEvent *e)
{
switch (e->type()) {
case QEvent::Timer:
timerEvent((QTimerEvent*)e);
break;
case QEvent::ChildAdded:
case QEvent::ChildPolished:
case QEvent::ChildRemoved:
childEvent((QChildEvent*)e);
break;
// ...
default:
if (e->type() >= QEvent::User) {
customEvent(e);
break;
}
return false;
}
return true;
}