Qt 事件的接收和忽略

在这里插入图片描述
我们可以把Qt的事件传递看成链状:如果子类没有处理这个事件,就会继续向其父类传递

1.新建一个myButton类,将其基类改为QPushButton.
2.在ui中新建一个Push Button控件,并将其提升为myButton.
3.在mybutton.h中增加鼠标按下事件.

#ifndef MYBUTTON_H
#define MYBUTTON_H

#include <QWidget>
#include<QPushButton>

class myButton : public QPushButton
{
    Q_OBJECT
public:
    explicit myButton(QWidget *parent = nullptr);
protected:
   void mousePressEvent(QMouseEvent *ev);

signals:

};

#endif // MYBUTTON_H

4.在mybutton.cpp中实现鼠标按下事件.
注意观察有和没有else时的执行结果!!

void myButton::mousePressEvent(QMouseEvent *ev)
{
    if(ev->button()==Qt::LeftButton)
    {
        qDebug()<<"按下的是左键";
        //事件的接收,如果这里按下的是左键,事件不再继续传递!!(Qt不会再去寻找其他的接受者,那么父类的操作也就不能进行,这可能会有潜在的危险)
        //ev->ignore();//执行ignore()后事件会继续传递,传递给谁呢?这里注意,是传递给父组件,不是父类!!
    }
    else//注意观察有和没有else时的执行结果!!
    {

        QPushButton::mousePressEvent(ev);
        //事件的忽略,这里如果按下的不是左键,事件继续传递给父类去处理
    }

}

mywidget.cpp:

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MyWidget)
{
    ui->setupUi(this);


    connect(ui->pushButton,&QPushButton::released,//事件传递给父类处理,这样在QPushButton::mousePressEvent(ev)就会发射信号,从而执行当前这句!!!
             [=]()
     {
         qDebug()<<"QPushButton::released";
     }
    );


}

ignore()函数:

在这里插入图片描述
可见,这个名字为pushButton的控件的父组件是MyWidget,父类是myButton.
所以执行 ev->ignore();后事件会继续传递,传递给父组件,不是父类!!

可以进行如下验证:
在mywidget.h中增加一个鼠标按下事件:

class MyWidget : public QWidget
{
    Q_OBJECT

public:
    MyWidget(QWidget *parent = nullptr);
    ~MyWidget();
protected:
    //鼠标按下事件
    void mousePressEvent(QMouseEvent *ev);


private:
    Ui::MyWidget *ui;
};

在mywidget.cpp中

void MyWidget::mousePressEvent(QMouseEvent *ev)
{
    qDebug()<<"MyWidget::mousePressEvent";

}

在mybutton.cpp中

void myButton::mousePressEvent(QMouseEvent *ev)
{
    if(ev->button()==Qt::LeftButton)
    {
        qDebug()<<"按下的是左键";
        ev->ignore();
    }
    else
    {

        QPushButton::mousePressEvent(ev);
       
    }

}

运行结果:
在这里插入图片描述
这就说明了执行 ev->ignore();后事件会继续传递给父组件,不是父类!

事实上,我们很少使用accept()和ignore()函数,而是像上面的示例一样,如果希望忽略事件,只要调用父类的响应函数即可。Qt中的事件大部分是protected的,因此,重写的函数必定存在着其父类中的响应函数,这个方法是可行的。

而accept()和ignore()函数的正确用法是用在重写CloseEvent函数中。见示例:

void MyWidget::closeEvent(QCloseEvent *event)
{
    int ret = QMessageBox::question(this,"question","是否要关闭窗口");
    if(ret == QMessageBox::Yes){
        event->accept();
    }else if(ret == QMessageBox::No){
        event->ignore();//继续传递给它的父组件
    }
}

在这里插入图片描述
这个事件所在的操作就是关闭窗口。因此,一旦接受事件,窗口就会被关闭;否则窗口继续保留。

发布了241 篇原创文章 · 获赞 4 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/ShenHang_/article/details/104962296