Qt进修之路(23):自界说事件
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的事件机制,包罗事件的派发、自界说等一系列的问题。下面的章节将继承我们的进修之路!
出处:http://devbean.blog.51cto.com/448512/232314