QT编程入门系列文章之二十三——自定义事件

在这里插入图片描述
  Qt允许你创建自己的事件类型,这在多线程的程序中尤其有用,当然,也可以用在单线程的程序中,作为一种对象间通讯的机制。那么,为什么 我需要使用事件,而不是使用信号槽呢?主要原因是,事件的分发既可以是同步的,又可以是异步的,而函数的调用或者说是槽的回调总是同步的。事件的另外一个 好处是,它可以使用过滤器。

Qt中的自定义事件很简单,同其他类似的库的使用很相似,都是要继承一个类进行扩展。在 Qt 中,你需要继承 的类是 QEvent。注意,在 Qt3 中,你需要继承的类是QCustomEvent,不过这个类在Qt4中已经被废除(这里的废除是不建议使用,并不是从 类库中删除)。

继承QEvent类,你需要提供一个QEvent::Type类型的参数,作为自定义事件的类型值。这里的 QEvent::Type类型是QEvent里面定义的一个 enum,因此,你是可以传递一个 int的。重要的是,你的事件类型不能和已经存在的 type 值重复,否则会有不可预料的错误发生!因为系统会将你的事件当做系统事件进行派发和调用。在Qt中,系统将保留0 - 999的值,也就是说,你的事件 type 要大于 999. 具体来说,你的自定义事件的 type 要在QEvent::User 和 QEvent::MaxUser 的 范 围 之 间 。 其 中 , QEvent::User 值 是 1000,QEvent::MaxUser的值是65535。从这里知道,你最多可以定义64536个事件,相信这个数字已经足够大了!但是,即便如此, 也只能保证用户自定义事件不能覆盖系统事件,并不能保证自定义事件之间不会被覆盖。为了解决这个问题,Qt 提供了一个函 数:registerEventType(),用于自定义事件的注册。该函数签名如下:

static int QEvent::registerEventType ( int hint = -1 );

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

你可以在QEvent子类中添加自己的事件所需要的数据,然后进行事件的发送。Qt中提供了两种发送方式:

* static bool QCoreApplication::sendEvent(QObjecy * receiver, QEvent * event):事件被QCoreApplication的notify()函数直接发送给receiver对象,返回值是事件处理函数的返回值。使用这个 函数必须要在栈上创建对象,例如:

QMouseEvent event(QEvent::MouseButtonPress, pos, 0, 0, 0);  QApplication::sendEvent(mainWindow, &event);

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

QApplication::postEvent(object, new MyEvent(QEvent::registerEventType(2048)));

这个对象不需要手动delete,Qt会自 动delete掉!因此,如果在post事件之后调用delete,程序可能会崩溃。另外,postEvent()函数还有一个重载的版本,增加一个优先 级参数,具体请参见API。通过调用sendPostedEvent()函数可以让已提交的事件立即得到处理。

如果要处理自定义事件, 可以重写 QObject的customEvent()函数,该函数接收一个QEvent对象作为参数。注意,在Qt3中这个参数是 QCustomEvent类型的。你可以像前面介绍的重写event()函数的方法去重写这个函数:

void CustomWidget::customEvent(QEvent *event) {

CustomEvent   *customEvent = static_cast<CustomEvent *>(event);

//…

}

另外,你也可以通过重写event()函数来处理自定义事件:

bool CustomWidget::event(QEvent *event) {

if (event->type() == MyCustomEventType) {

CustomEvent *myEvent = static_cast<CustomEvent *>(event);

// processing…

return true;

}

return QWidget::event(event);

}

这两种办法都是可行的。

好 了,至此,我们已经概略的介绍了 Qt的事件机制,包括事件的派发、自定义等一系列的问题。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习成长分享快乐

您的鼓励是我前进的不竭动力~~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值