您的位置:首页 > 编程语言 > Qt开发

QT事件(4)

2015-09-08 10:35 453 查看
QT事件(3)里说到了event函数有屏蔽拦截事件的功能,但是当有很多组件的时候,岂不是要重写很多个event函数?而且重写event函数还得注意一大堆问题,比如说什么时候去调用父类的event函数等问题。那么这个时候我们可以用QT提供的事件过滤器eventFilter(QObject *obj, QEvent *e),这个函数相当于创建一个过滤器,属于QObject里的成员函数,obj表示要监视的对象。我们可以重写eventFilter(QObject
*obj, QEvent *e)这个函数来对我们不关心的事件进行过滤拦截。

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);

private:
    QTextEdit *edit,*edit1;
protected:
    bool eventFilter(QObject *, QEvent *);

};
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    edit = new QTextEdit(this);
    edit->installEventFilter(this);
    edit->resize(100,50);
    edit->show();
}

bool Widget::eventFilter(QObject *obj, QEvent *e){
    if(obj == edit){
        if(e->type() == QEvent::KeyPress){
            QKeyEvent *keyevent = static_cast<QKeyEvent *>(e);
            if(keyevent->key() == Qt::Key_Space){
              qDebug()<<"press key_space";
              return true;
            }
            else
                return false;
        }
        else
            return false;
    }
    else
        return QWidget::eventFilter(obj,e);

}
int main(int argc, char *argv[])
{
    QApplication a(argc, argv); 
    Widget *widget = new Widget;
    widget->resize(320,240);
    widget->show();
    return a.exec();
}


上面的代码是我们写了一个Widget类继承于QWidget,然后重写Widget里的事件过滤器,事件过滤器里针对的是edit对象。eventFilter(QObject *obj, QEvent *e)的返回类型是bool类型,返回true,表示过滤掉,不再转发事件,返回false表示该事件还要继续转发处理。我们来仔细看下eventFilter(QObject
*obj, QEvent *e)里的代码,它先判断obj是不是edit,是的话就执行if里面的语句,然后再判断是不是键盘按下,是的话再去判断是不是空格键按下,是的话就打印press key_space语句,并返回true,这里我们可以看出,这事件过滤器想屏蔽的是edit按下空格产生的事件。所以代码执行后,你在edit上面按下空格,光标并不会移动一个空格,只会打印press key_space这条语句,但不影响键盘上其他键的使用,这说明我们对在edit按下空格的事件成功的屏蔽掉。

值得注意的是eventFilter(QObject *obj, QEvent *e)只是创建事件过滤器而已,真正要使用他还得安装edit->installEventFilter(this)这句话就是安装语句。installEventFilter(QObject
*obj)这句话调用相当于是谁调用它就把obj里的事件过滤器安装给谁。当你想移除事件过滤器是可以调用removeEventFilter()这个函数。

另外以下这些注意事项都是在网上搜集下来的:

1.事件过滤器的强大之处在于,我们可以为整个应用程序添加一个事件过滤器。记得,installEventFilter()函数是QObject的函数,QApplication或者QCoreApplication对象都是QObject的子类,因此,我们可以向QApplication或者QCoreApplication添加事件过滤器。这种全局的事件过滤器将会在所有其它特性对象的事件过滤器之前调用。尽管很强大,但这种行为会严重降低整个应用程序的事件分发效率。因此,除非是不得不使用的情况,否则的话我们不应该这么做。

2。注意,如果你在事件过滤器中 delete 了某个接收组件,务必将函数返回值设为 true。否则,Qt 还是会将事件分发给这个接收组件,从而导致程序崩溃。

3.事件过滤器和被安装过滤器的组件必须在同一线程,否则,过滤器将不起作用。另外,如果在安装过滤器之后,这两个组件到了不同的线程,那么,只有等到二者重新回到同一线程的时候过滤器才会有效。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: