第6章 事件系统
事件作为一个对象,继承自QEvent类,除常规事件外,还涉及事件过滤器、自定义事件、随机数。
6.1 Qt中的事件
事件是由应用程序内部或者外部产生的事情或者动作的通称。事件与信号并不相同,事件与信号是两个层面的东西,发出者不同,作用也不同。在Qt中,任何QObject子类实例都可以接收和处理事件。
常用事件,上下文菜单事件QContexMenuEvetn和关闭事件QCloseEvent、拖放事件、绘制事件QPaintEvent。
6.1.1 事件处理
一个事件又包含多个事件类型,这些事件类型都由QEvent类的枚举型QEvent::Type来表示。QCoreApplicationod 的 notify()函数。
方法1:重新实现部件的事件处理函数,不过只能用来处理特定部件的特定事件。
方法2:重新实现notify()函数,可以在事件过滤器得到事件之前就获得它们,但是,一次只能处理一个事件??
方法3:向QApplication对象上安装事件过滤器。实现的功能与使用notify()函数是相同的优点是可以同时处理多个事件。
方法4:重新实现event()函数。QObject类的event()函数可以在事件到达默认的事件处理函数之前获得该事件。
方法5:在对象上安装事件过滤器。使用事件过滤器可以在一个界面类中同时处理不同子部件的不同事件。
过程:调用QApplication类的exec()函数,它会使用Qt应用程序进入事件循环,这样可以使应用程序在运行时接收发生的各种事件。一旦有事件发生,Qt便会构建一个相应的QEvent子类的对象来表示它,然后将它传递给相应的QObject对象或其子对象。
event->ignore() 事件是先传递给指定窗口部件的,确切地说应该是先传递给获得焦点的窗口部件。但是如果该部件忽略掉该事件,那么这个事件就会传递给这个部件的父部件。重新实现事件处理函数时,一般要调用的相应事件处理函数来实现默认操作。一般是返回父类的event()函数的操作结果。
事件的传递顺序是:先是事件过滤器,然后是焦点部件的event()函数,最后是焦点部件的事件处理函数;如果焦点部件忽略了该事件,那么会执行父部件的事件处理函数。
注意:event()函数和事件处理函数是在焦点部件内重新定义的,而事件过滤器却是在焦点部件的父部件中定义的。
6.2 鼠标事件和 滚轮事件
QMouseEvent类用来表示一个鼠标事件,在窗口部件中按下鼠标或者移动鼠标指针时,会产生鼠标事件,可以获知鼠标是哪个键按下了、鼠标指针的当前位置等信息。
QWheelEvent类用来表示鼠标滚轮事件,用来获取滚轮移动的方向和距离。
Q_UNUSED();
如果想不按鼠标按键,也可以获取鼠标移动事件,那么就要在构造函数中添加下面一行代码:
setMouseTracking(true);//设置鼠标跟踪
6.3 键盘事件
QKeyEvent的key()函数可以获取具体的按键,回车键在这里时Qt::Key_Return;键盘上的一些修饰键,比如Ctrl和Shift,这里需要使用QKeyEvent的modifiers()函数来获取。
setWindowState(Qt::WindowMaximized);
如果只是按了一下按键,那么便不会自动重复,但是,如果一直按着这个按键,那么它就会实现这样的效果。event->isAutoRepeat()//判断按键是否重复。
6.4 定时器事件与随机数
QTimerEvent类用来描述一个定时器事件。QObject子类,只需要使用int QObject::startTimer(int interval)函数就可以开启一个定时器,函数返回一个整型编号来代表这个定时器,当定时器溢出时可以在timerEvent()函数中进行需要的操作。
QTimer类来实现一个定时器,还可以设置只运行一次的定时器。event->timeId()//判断是那个定时器。
QTimer * timer = new QTimer(this);
connect(timer,&QTimer::timeout,this,&Widget::timeUpdate);
timer->start(1000);
如果想停止一个定时器,可以调用它的stop()函数。
给随机数附初值:qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
QTimer::singleShot(10000,this,&Widget::close);//开启一个只运行一次的定时器。
6.5 事件过滤器与事件的发送
事件过滤器与其他部件不同,它不是一个类,只是由两个函数组成的一种操作,用来完成一个部件对其他部件的事件的监视。
installEventFilter() 和 eventFilter()都是QObject类中的函数。
在事件过滤器中先判断部件的类型,然后再判断事件的类型,如果是需要的事件,那么 就将其进行强制类型转换,然后进行相应的处理。如果要对一个特定的事件进行处理,而且不希望它在后面的传递过程中再被处理,那么就返回true,否则就返回false。
Qt提供了发送一个事件的功能:bool QCoreApplication::sendEvent(QObject * receiver,QEvent * event)或者 void QCoreApplication::postEvent(QObject*receiver,QEvent* event,int priority = Qt::NormalEventPriority)
sendEvent()会立即处理,postEvent()将事件放到等待队列中。
sendEvent()需要在栈上创建QEvent对象;而postEvent()中的QEvent对象参数必须在堆上进行创建。

浙公网安备 33010602011771号