博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Qt学习之路(23): 自定义事件
阅读量:6858 次
发布时间:2019-06-26

本文共 2331 字,大约阅读时间需要 7 分钟。

这部分将作为Qt事件部分的结束。我们在前面已经从大概上了解了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(),用于自定义事件的注册。该函数签名如下:


InBlock.gif
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对象,返回值是事件处理函数的返回值。使用这个函数必须要在栈上创建对象,例如:
    InBlock.gifQMouseEvent 
    event(QEvent::MouseButtonPress, pos, 0, 0, 0);

    InBlock.gifQApplication::sendEvent(mainWindow, &
    event);
  • static bool QCoreApplication::postEvent(QObject * receiver, QEvent * event):事件被QCoreApplication追加到事件列表的最后,并等待处理,该函数将事件追加后会立即返回,并且注意,该函数是线程安全的。另外一点是,使用这个函数必须要在堆上创建对象,例如:
    InBlock.gifQApplication::postEvent(
    object
    new MyEvent(QEvent::registerEventType(2048)));
    这个对象不需要手动delete,Qt会自动delete掉!因此,如果在post事件之后调用delete,程序可能会崩溃。另外,postEvent()函数还有一个重载的版本,增加一个优先级参数,具体请参见API。通过调用sendPostedEvent()函数可以让已提交的事件立即得到处理。
如果要处理自定义事件,可以重写QObject的customEvent()函数,该函数接收一个QEvent对象作为参数。注意,在Qt3中这个参数是QCustomEvent类型的。你可以像前面介绍的重写event()函数的方法去重写这个函数:


InBlock.gif
void CustomWidget::customEvent(QEvent *
event) {

InBlock.gif        CustomEvent *customEvent = static_cast<CustomEvent *>(
event);

InBlock.gif        
// ....

InBlock.gif}

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


InBlock.gif
bool CustomWidget::
event(QEvent *
event) {

InBlock.gif        
if (
event->type() == MyCustomEventType) {

InBlock.gif                CustomEvent *myEvent = static_cast<CustomEvent *>(
event);

InBlock.gif                
// processing...

InBlock.gif                
return 
true;

InBlock.gif        }

InBlock.gif

        
return QWidget::
event(
event);

InBlock.gif}

这两种办法都是可行的。


好了,至此,我们已经概略的介绍了Qt的事件机制,包括事件的派发、自定义等一系列的问题。下面的章节将继续我们的学习之路!

本文转自 FinderCheng 51CTO博客,原文链接:

http://blog.51cto.com/devbean/232314

转载地址:http://qdiyl.baihongyu.com/

你可能感兴趣的文章
9、如何清空流及缓存
查看>>
gvim汉化及配置
查看>>
ubuntu下JMF RTP不支持单播接收
查看>>
fastboot烧写命令
查看>>
深度测试与alpha混合(1)
查看>>
15幅非常有创意的影子摄影作品欣赏
查看>>
SQL Server 2008 VALUES
查看>>
[算法] 已知在平面坐标系内有N个点,求离开给定坐标距离最近的10个点
查看>>
使用DMV和DMF分析数据库性能
查看>>
PHP验证IP地址输入的准确性:数组数值验证
查看>>
HashMap概述
查看>>
在rem布局下使用背景图片以及sprite
查看>>
JAVA设计模式之【抽象工厂模式】
查看>>
数字电视的电子节目指南(EPG)及其系统
查看>>
11 复用与多址
查看>>
附录A 编译安装Hadoop
查看>>
android studio building project info 错误
查看>>
【Scala】Scala之Control Structures
查看>>
三星手机拍照,从图库选择照片旋转问题完美解决
查看>>
算法笔记_173:历届试题 斐波那契(Java)
查看>>