Qt知识回顾(五)——事件系统

在Qt中,事件作为一个对象,继承自QEvent类,常见的有键盘事件QKeyEvent、鼠标事件QMouseEvent和定时器事件QTimerEvent等,QEvent类的关系图如下:
在这里插入图片描述

Qt中的事件

  事件是对各种应用程序需要知道的由应用程序内部或者外部产生的事情或者动作的简称。Qt中使用一个对象来表示一个事件,继承自QEvent类。需要说明的是,事件与信号并不相同,比如单击一下界面上的按钮,那么就会产生鼠标事件QMouseEvent(不是按钮产生的),而因为按钮被按下了,那么它会发射clicked()单击信号(是按钮产生的)。这里一般只关心按钮的单击信号,而不用考虑鼠标事件,但是如果要设计一个按钮,或者单击按钮时让它产生别的效果,那么就要关心鼠标事件了。可以看到,事件与信号是两个层面的东西,发出者不同,作用也不同。在Qt中,任何QObject子类实例都可以接收和处理事件。

事件的处理

  一个事件由一个特定的QEvent子类来表示,但是有时一个事件又包含多个事件类型,比如鼠标事件又可以分为鼠标按下、双击、和移动等多种操作。这些事件类型都可以由QEvent类的枚举类型QEvent::Type来表示,其中包含了一百多种事件类型,可以在QEvent类的帮助文档中进行查看。虽然QEvent的子类可以表示一个事件,但是却不能用来处理事件,QCoreApplication类的notify()函数的帮助文档给出了5中处理时间的方法:
①重新实现部件的paintEvent()、mousePressEvent()等事件处理函数。这是最常用的一种方法,不过只能用来处理特定部件的特定事件。
②重新实现notify()函数,这个函数功能强大1,提供了完全的控制,可以在事件过滤器得到事件之前就获得它们。但是,它一次只能处理一个事件。
③向QApplication对象上安装事件过滤器,因为一个程序只有一个QApplication对象,所以这样实现的功能与使用notify()函数是相同的,优点是可以同时处理多个事件。
④重新实现event()函数。QObject类的event()函数可以在事件到达默认的事件处理函数之前获得该事件。
⑤在对象上安装事件过滤器。使用事件过滤器可以在一个界面类中同时处理不同子部件的不同事件。
  在实际编程中,最常用的方法①,其次是方法⑤。因为方法②需要继承自QApplication类;而方法③要使用一个全局的事件过滤器,这将减缓事件的传递。

事件的传递

  事件的传递顺序:先是事件过滤器,然后是焦点部件的event()函数,最后是焦点不见得事件处理函数;如果焦点部件忽略了该事件,那么会执行父窗口的事件处理函数。如下图:
在这里插入图片描述

鼠标事件和滚轮事件

  QMouseEvent类用来表示一个鼠标事件,在窗口部件中按下鼠标或者移动鼠标指标的当前位置等信息。利用QMouseEvent类可以获知鼠标是哪个键按下了、鼠标指针的当前位置等信息。通常是重定义部件的鼠标事件处理函数来进行一些自定义的操作。QWheelEvent类用来表示鼠标滚轮事件,主要用来获取滚轮移动的方向和距离。

键盘事件

  QKeyEvent类用来描述一个键盘事件。当键盘按键按下或者被释放时,键盘事件便会被发送给拥有键盘输入焦点的部件。QKeyEvent的key()函数可以获得具体的按键,对于Qt中给定的按键,可以在帮助中通过Qt::Key关键字查看。(回车键在这里是Qt::Key_Return;键盘上的一些修饰键,比如Ctrl和Shift等,这里需要使用QKeyEvent的modifiers()函数来获取,可以在帮助中使用Qt::KeyboardModifier关键字来查看所有的修饰键)。

定时器事件与随机数

   QTimeEvent类用来描述一个定时器事件,对于一个QObject的子类,只需要使用 int QObject::startTimer(int interval)函数就可以开启一个定时器,这个函数需要输入一个以毫秒为单位的整数作为参数来表明设定的事件,函数返回一个整型编号来代表这个定时器。当定时器溢出时可以在timeEvent()函数中进行需要的操作。
   其实编程中更多的是使用QTimer类来实现一个定时器,它提供了更高层次的编程接口,比如可以使用信号和槽,还可以设置只运行一次的定时器。如果使用定时器,那么一般都是使用的QTime类。关于定时器的介绍,可以在帮助中通过Timers关键字查看。
   关于随机数,Qt是使用qrand()和qsrand()两个函数实现的。

事件过滤器与事件的发送

   Qt中提供了事件过滤器来实现在一个部件中监视其他多个部件的事件。事件过滤器与其他部件不同,他不是一个类,只是由两个函数组成的一种操作,用来完成一个部件对其他部件的事件的监视。这两个函数分别是InstallEventFilter()和eventFilter(),都是QObject类的函数。
   Qt中也提供了发射一个事件的功能,它是由QCoreApplication类的bool QCoreApplication::sendEvent(QObject* receiver,QEvent *event);函数或者void QCoreApplication::posEvent(QObject *receiver,QEvent* event,int priority =Qt::NormalEventPriority);函数来实现。这两个函数的主要区别是:sendEvent()会立即处理给定的事件,而postEvent()则会将事件放到等待调度队列中,当下一次Qt的主事件循环运行时才会处理它。这两个函数还有其他一些区别,比如sendEvent()中的QEvent对象参数在事件发送完成后无法自动删除,所以需要在栈上创建QEvent对象;而postEvent()中的QEvent对象参数必须在堆上进行创建,当事件被发送后事件队列会自动删除它。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值