QPushButton的鼠标事件处理及EventFilter事件过滤器的用法

来源:互联网 发布:php require use 编辑:程序博客网 时间:2024/04/27 05:52

        这两天在做一个软键盘,支持QLineEdit的输入,原来都是处理的keyPressEvent,现在用的是mousePressEvent,移植原来的代码居然不行。折腾了半天发现,QPushButton自身会处理到鼠标左键的单击事件,即使你用了事件过滤器也不行!具体验证了三种情况:

(1)QPushButton类会处理鼠标左键单击事件,不会再向父窗口传递,父窗口的eventFilter也无法捕捉这个事件。

(2)同在一个窗口的QLabel可以在父窗口eventFilter被捕捉

(3)继承QPushButton重新实现鼠标事件,还是不能被eventFilter捕捉,但是这样可以独立处理鼠标单击事件。

代码如下,有两种情况可以根据if、else进行选择编译:

1.dailog.h

#ifndef DIALOG_H#define DIALOG_H#include <QDialog>#include <QPushButton>#if 0class Dialog : public QDialog{    Q_OBJECTpublic:    Dialog(QWidget *parent = 0);    ~Dialog();    bool eventFilter(QObject *obj, QEvent *event);    void mousePressEvent(QMouseEvent *event);    //注意这里不要写成(QKeyevent *event),否则接收不到鼠标事件    void mouseReleaseEvent(QMouseEvent *event);   //注意这里不要写成(QKeyevent *event),否则接收不到鼠标事件};#elseclass Dialog : public QDialog{    Q_OBJECTpublic:    Dialog(QWidget *parent = 0);    ~Dialog();    bool eventFilter(QObject *obj, QEvent *event);    void mousePressEvent(QMouseEvent *event); //注意这里不要写成(QKeyevent *event),否则接收不到鼠标事件};class myButton : public QPushButton{    Q_OBJECTpublic:    myButton(QWidget *parent = 0);    myButton(const QString & text, QWidget *parent = 0);    ~myButton();    void mousePressEvent(QMouseEvent *event); //注意这里不要写成(QKeyevent *event),否则接收不到鼠标事件    void mouseReleaseEvent(QMouseEvent *event); //注意这里不要写成(QKeyevent *event),否则接收不到鼠标事件};#endif#endif // DIALOG_H


2.dialog.cpp

#include "dialog.h"#include <QPushButton>#include <QDebug>#include <QEvent>#include <QKeyEvent>#include <QLabel>/******************************************************************** *  QPushButton本身就相应鼠标的左键的单击事件!!!!! * 以下是两种情况来验证qt事件过滤器对于QPustButton的鼠标事件的影响: * 1.直接使用QPushButton类; * 2.继承QPushButton类,重写mousePressEvent、mouseReleaseEvent事件。 ********************************************************************/#if 0/*运行程序,分别点击QPushButton按钮、QLabel按钮,通过打印可以看出事件过滤器对QPushButton的鼠标事件无法过滤,同在一 * 个窗口的QLabel鼠标事件却能够过滤,可见QPushButton对于鼠标事件进行了直接处理,过滤器无法拦截;QLabel的鼠标事件则可 * 以进行拦截。*/Dialog::Dialog(QWidget *parent)    : QDialog(parent){    QPushButton *btn = new QPushButton("QPushButton", this);    btn->resize(100,50);    btn->move(100,50);    QLabel *label = new QLabel("QLabel", this);    label->setStyleSheet("border:2px solid green;border-radius: 3px;background: #EEEEEE");    label->resize(100, 50);    label ->move(100,150);    //事件过滤器用法:A->installEventFilter(B)表示通过B中定义的事件过滤器来监控A,A是被监控者!    this->installEventFilter(this);    resize(300, 300);}Dialog::~Dialog(){}bool Dialog::eventFilter(QObject *obj, QEvent *event){    //qDebug()<<"Dialog::eventFilter"<<event->type();    if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease)    {        qDebug()<<"Dialog::eventFilter received mouse event!"<<event->type();        //return true,不让它继续传递了,这样Dialog::mousePressEvent()就不会有打印;        //return false,事件将接着被送往剩下的事件过滤器或是目标对象进行处理,Dialog::mousePressEvent()有打印        return false;    }    return QObject::eventFilter(obj, event); //按照默认的处理方式继续传递}void Dialog::mousePressEvent(QMouseEvent *event)  //注意这里不要写成(QKeyevent *event),否则接收不到鼠标事件{    qDebug()<<"Dialog::mousePressEvent"<<event->type();}void Dialog::mouseReleaseEvent(QMouseEvent *event) //注意这里不要写成(QKeyevent *event),否则接收不到鼠标事件{    qDebug()<<"Dialog::mouseReleaseEvent"<<event->type();}#elseDialog::Dialog(QWidget *parent)    : QDialog(parent){    myButton *btn = new myButton("Button",this);    btn->resize(100,50);    btn->move(100,50);    this->installEventFilter(this);    resize(300, 300);}Dialog::~Dialog(){}bool Dialog::eventFilter(QObject *obj, QEvent *event){    //qDebug()<<"Dialog::eventFilter"<<event->type();    if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease)    {        qDebug()<<"Dialog::eventFilter received mouse event!"<<event->type();    }    return QObject::eventFilter(obj, event);}void Dialog::mousePressEvent(QMouseEvent *event){    qDebug()<<"Dialog::mousePressEvent"<<event->type();}//下面的QPushButton(text, parent)是在初始化列表中调用了基类的构造函数对基类对象进行初始化,因为构造子类时,基类构造函数//先要被调用,基类有两个构造函数QPushButton(const QString & text, QWidget * parent = 0)和QPushButton(QWidget * parent = 0)//我测试了下,随便你初始化哪个都行,但是如果用第二个就只能在构造函数里设置文本信息。//关于利用列表初始化中调用基类构造具体可以参考:http://blog.csdn.net/bdss58/article/details/40348901myButton::myButton(QWidget *parent):QPushButton(parent){} //这样可以的//myButton::myButton(QWidget *parent):QPushButton("Button", parent) {}//这样居然也是可以的myButton::myButton(const QString & text, QWidget *parent ): QPushButton(text, parent)//还是这个方便{}myButton::~myButton(){}void myButton::mousePressEvent(QMouseEvent *event) //注意这里不要写成(QKeyevent *event),否则接收不到鼠标事件{    qDebug()<<"myButton::mousePressEvent"<<event->type();}void myButton::mouseReleaseEvent(QMouseEvent *event) //注意这里不要写成(QKeyevent *event),否则接收不到鼠标事件{    qDebug()<<"myButton::mouseReleaseEvent"<<event->type();}#endif

3.main.cpp

#include "dialog.h"#include <QApplication>int main(int argc, char *argv[]){    QApplication a(argc, argv);    Dialog w;    w.show();    return a.exec();}

注释很详细,不再赘述!

不错的参考资料:

QT父子窗口事件传递与事件过滤器

浅谈Qt事件的路由机制:鼠标事件

为什么鼠标左击事件不响应呢?

0 0
原创粉丝点击