虽然Qt是跨平台的C++开发框架,Qt的很多能力其实是操作系统提供的,只不过Qt封装了系统的API。程序试是运行在操作系统上的,需要操作系统给我们通过支撑。
一、事件
1、事件的概念
用户进行各种操作的时候。就可能会产生出信号,可以给某个信号指定槽函数,当信号触发时,就能够自动地执行对应的槽函数。
事件也非常相似,用户进行的各种操作,也会产生事件,程序员同样可以给事件关联处理函数,当事件触发的时候,就能够执行对应的处理函数。
事件本身是操作系统提供的机制,Qt也同样把操作系统事件机制进行了封装,拿到Qt中。但是由于事件对应的代码编写起来很不方便,Qt就对事件机制又进一步进行了封装,就得到了信号槽机制。所以,信号槽就是对事件的进一步封装,事件就是信号槽的底层机制。
实际Qt开发程序过程中,绝大部分和用户之间进行的交互都是通过信号槽来完成的。但是有些特殊情况下,信号槽不一定能搞定,Qt没有提供对应的信号。此时就需要通过重写事件处理函数的形式,来手动处理事件的响应逻辑。
2、事件的处理
事件的处理方法一般是让当前的类,重写某个事件处理函数。使用了多态机制,创建子类继承Qt已有的类,在子类中重写父类的事件处理函数。后序事件触发过程中,就会通过多态的机制,执行自定义子类重写的函数。
举个例子,处理一下鼠标进入和离开事件:
鼠标进入是enterEvent,鼠标离开是leaveEvent。我们要创建一个QLabel的子类,然后重写enterEvent和leaveEvent。
在Qt Designer中创建QLabel,然后通过点击“提升为”将其变为我们自定义的Label。
2.1、鼠标事件
处理鼠标按下事件:
mousePressEvent方法是在鼠标按下时触发的事件处理函数。这个函数在按下鼠标左键、右键、滚轮都能触发,有的鼠标还有前进后退侧键,也可以触发。但又还有的鼠标,有更多的按键,就不一定能触发了。
处理鼠标释放事件与双击事件:
clicked信号就相当于一次按下事件+一次释放事件。
处理鼠标移动事件:
在上面的例子中,重写鼠标事件都是在自定义Label中完成的,此时鼠标只有在Label范围内活动,才能捕捉到。其实也可以直接把这些操作放到Widget(QWidget子类)中完成,这样的话,鼠标在整个窗口中进行的各种动作都能捕获了。
鼠标移动不同于鼠标按下,随便移动一下鼠标,就会产生大量的鼠标移动事件,当我们进行捕获时间的时候,尤其是在进行一些复杂逻辑时,程序负担就会很重,很容易产生卡顿之类的情况。Qt为了保证程序的流畅性,默认情况下不会对鼠标移动进行追踪,鼠标移动的时候不会调用mouseMoveEvent,除非显式地告诉Qt就是要追踪鼠标位置。如何告诉Qt呢?通过setMouseTracking方法把Widget的属性设置为true才能追踪鼠标的移动位置。
2.2、鼠标滚轮事件
2.3、键盘事件
Qt把一些用来搭配组合键的功能键单独拎出来了,使用modifiers方法。