Qt事件基本了解[2014/03/23]

来源:互联网 发布:淘宝靠谱的口红代购 编辑:程序博客网 时间:2024/05/20 21:18

最近学习了Qt学习之路中的事件,对此进行各总结和测试,做一个对事件的基本认识。


事件与信号槽区别,信号槽是同步的,而事件可以同步和异步的,如sendEvent直接发给接受者,postEvent投递到事件队列队尾,前面处理完了再处理。

信号是由具体对象发出,直接调用接收者的对应slot函数,而事件时有Qt统一管理的。


Qt的事件大体分为以下层次:

1.QCoreApplication::notify()

2.QApplicationm::eventFilter()

3.QApplication::event()

4.组件的eventFilter()

5.组件的event()

6.组件的一些现有事件函数如keyPressEvent等

1.事件过滤器

virtual boolQObject::eventFilter( QObject *watched, QEvent *event )

重写过滤器,对事件进行过滤。

若对事件过滤则return true反之return false

同时还得对事件过滤器安装

void QObject::installEventFilter( QObject * filterObj)


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

事件过滤器和被安装的组件必须在同一线程, 否则,过滤器不起作用。另外,如果在install 之后,这两个组件到了不同的线程,那么,只有等到二者重新回到同一线程的时候
过滤器才会有效。


2.事件分发函数

event() 函数主要用于事件的分发,所以,如果你希望在事件分发之前做一些操作,那么,就需要注意这个 event()函数了。 为了达到这种目的,我们可以重写 event()函数。

bool QObject::event(QEvent *event)
return true 告知QCoreApplication::notfiy()已经处理事件

return QWidget::event(event) 由父类继续事件处理

3.自定义事件

Qt 中的自定义事件,需要继承 的类是 QEvent。

继承 QEvent 类,你需要提供一个 QEvent::Type 类型的参数,作为自定义事件的类型值

你的自定义事件的 type 要 在QEvent::User 和 QEvent::MaxUser 的 范 围 之 间 。 其 中 , QEvent::User 值 是 1000,QEvent::MaxUser 的值是 65535。 从这里知道,你最多可以定义 64536 个事件。

static int  QEvent::registerEventType ( int hint = -1 );
函数是 static 的,因 此可以使用 QEvent 类直接调用。函数接受一个 int 值,其默认值为-1,返回值是创建的这个 Type 类型的值。如果 hint 是合法的,不会发生任何覆 盖,则会返回这个值;如果 hint 不合法,系统会自动分配一个合法值并返回。 因此,使用这个函数即可完成 type 值的指定。这个函数是线程安全的,因此不 必另外添加同步。


static  bool  QCoreApplication::sendEvent(QObjecy   *   receiver,  QEvent  *event)

事件被 QCoreApplication 的 notify()函数直接发送给 receiver 对象,返回值是事件处理函数的返回值。使用这个 函数必须要在栈上创建对象


static  bool  QCoreApplication::postEvent(QObject  *   receiver,  QEvent  *event)

事件被 QCoreApplication 追加到事件列表的最后,并等待处理,该函数将事件追加后会立即返回,并且注意,该函数是线程安全的。 另外一点是,使用这个函数必须要在堆
上创建对象

这个对象不需要手动 delete,Qt 会自 动 delete 掉!因此,如果在 post 事件之后调用delete,程序可能会崩溃


如果要处理自定义事件, 可以重写 QObject 的 customEvent()函数或者在event()函数中处理。


下面是整个一起的代码,比较偷懒。


#ifndef MYEVENT_H#define MYEVENT_H#include <QString>#include <QEvent>class MyEvent : public QEvent{public:    MyEvent(Type type,const QString &msg);    QString getMsg();    bool setMsg(QString &msg);private:    QString  _msg;};#endif // MYEVENT_H

#include "myevent.h"MyEvent::MyEvent(Type type,const QString &msg):         QEvent(type){    _msg = msg;}QString MyEvent::getMsg(){   return _msg;}bool MyEvent::setMsg(QString &msg){   _msg = msg;   return true;}

#include "widget.h"#include "ui_widget.h"Widget::Widget(QWidget *parent) :    QWidget(parent),    ui(new Ui::Widget){    ui->setupUi(this);    installEventFilter(this);    evenType = QEvent::registerEventType(QEvent::User+1);}Widget::~Widget(){    delete ui;}bool Widget::eventFilter( QObject * watched, QEvent * event){    if(watched == this){        if(event->type() == QEvent::KeyPress){            qDebug()<<"key press(eventFilter)\n";        }    }    return false;}bool Widget::event(QEvent * e){    if(e->type() == QEvent::KeyPress){      qDebug()<<"key press(event)\n";      keyPressEvent((QKeyEvent *)e);      return true;    }    return QWidget::event(e);}void Widget::keyPressEvent(QKeyEvent * event){    if(event->type() == QEvent::KeyPress){        qDebug()<<"key press(keyPressEvent)\n";        QApplication::postEvent(this,new MyEvent((QEvent::Type)evenType,tr("hello event")));    }}void Widget::customEvent (QEvent * event){    if(event->type() == evenType){        MyEvent *e = static_cast<MyEvent *>(event);        qDebug()<<"custom envent\n";        qDebug()<<e->getMsg();    }}

对于Qt的事件到此,也算是基本了解。






0 0
原创粉丝点击