Qt中事件的传递

每个程序main()的最后调用QApplication类的exec(),它会使应用程序进入事件循环,这样就可以使应用程序在运行时接收发生的各种事件。一旦有事件发生,Qt便会构建一个相应的QEvent子类的对象来表示它。

以下是事件传递的例子:

//mylineedit.h
#ifndef MYLINEEDIT_H
#define MYLINEEDIT_H
#include<QLineEdit>

class MyLineEdit:public QLineEdit//手动添加LineEdit
{
    Q_OBJECT
public:
    MyLineEdit(QWidget *parent = 0);
protected:
    void keyPressEvent(QKeyEvent *e);
};

#endif // MYLINEEDIT_H
//mylineedit.cpp
#include "mylineedit.h"
#include<QKeyEvent>
#include<QDebug>
MyLineEdit::MyLineEdit(QWidget *parent):QLineEdit(parent)
{

}

void MyLineEdit::keyPressEvent(QKeyEvent *e)
{
    qDebug()<<tr("MyLineEdit键盘按下事件");
}
//widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}
class MyLineEdit;//前置声明
class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private:
    Ui::Widget *ui;
    MyLineEdit *lineEdit;
protected:
    void keyPressEvent(QKeyEvent *e);
};

#endif // WIDGET_H
//widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include"mylineedit.h"
#include<QKeyEvent>
#include<QDebug>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    lineEdit = new MyLineEdit(this);
    lineEdit->move(100,100);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::keyPressEvent(QKeyEvent *e)
{
    qDebug()<<tr("Widget键盘按下事件");
}
//main.cpp
#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

结果为:

说明这时只执行了MyLineEdit类中的keyPressEvent()函数。

接下来继续对程序进行如下改动:

//mylineedit.h
#include "mylineedit.h"
#include<QKeyEvent>
#include<QDebug>
MyLineEdit::MyLineEdit(QWidget *parent):QLineEdit(parent)
{

}

void MyLineEdit::keyPressEvent(QKeyEvent *e)
{
    qDebug()<<tr("MyLineEdit键盘按下事件");
    QLineEdit::keyPressEvent(e);//执行QLineEdit类的默认事件处理
    e->ignore();//忽略该事件
}

结果为:

说明事件先传递给获得焦点的窗口部件,但如果该部件忽略掉该事件,这个事件就会传递给这个部件的父部件。

继续对程序进行如下改动:

//widget.h
#ifndef WIDGET_H
#define WIDGET_H


#include <QWidget>

namespace Ui {
class Widget;
}
class MyLineEdit;
class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    bool eventFilter(QObject *obj, QEvent *event);//事件过滤

private:
    Ui::Widget *ui;
    MyLineEdit *lineEdit;
protected:
    void keyPressEvent(QKeyEvent *e);
};

#endif // WIDGET_H
//widget.h
#include "widget.h"
#include "ui_widget.h"
#include"mylineedit.h"
#include<QKeyEvent>
#include<QDebug>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    lineEdit = new MyLineEdit(this);
    lineEdit->move(100,100);
    lineEdit->installEventFilter(this);//在Widget上为lineEdit安装事件过滤器
}

Widget::~Widget()
{
    delete ui;
}

bool Widget::eventFilter(QObject *obj, QEvent *event)
{
    if(obj == lineEdit){//先判断事件对象是不是lineEdit
        if(event->type() == QEvent::KeyPress)//判断事件类型
            qDebug()<<tr("Widget的事件过滤器");
    }
    return QWidget::eventFilter(obj, event);
}

void Widget::keyPressEvent(QKeyEvent *e)
{
    qDebug()<<tr("Widget键盘按下事件");
}

结果为:

说明事件的传递顺序是:事件过滤器 --> 焦点部件的event()函数 --> 焦点部件的事件处理函数 --> 父部件的事件处理函数。

posted @ 2017-05-09 20:21  奇热行  阅读(372)  评论(0)    收藏  举报