QT程序设计编程进阶-事件.ppt
《QT程序设计编程进阶-事件.ppt》由会员分享,可在线阅读,更多相关《QT程序设计编程进阶-事件.ppt(37页珍藏版)》请在三一办公上搜索。
1、QT程序设计进阶-事件,www.gec-edu.org,www.gec-edu.org,QT的事件机制,Qt事件 Qt程序是事件驱动的,程序的每个动作都是由幕后某个事件所触发.Qt事件的类型很多,常见的qt的事件如下:键盘事件:按键按下和松开.鼠标事件:鼠标移动,鼠标按键的按下和松开.拖放事件:用鼠标进行拖放.滚轮事件:鼠标滚轮滚动.绘屏事件:重绘屏幕的某些部分.定时事件:定时器到时.焦点事件:键盘焦点移动.进入和离开事件:鼠标移入widget之内,或是移出.移动事件:widget的位置改变.大小改变事件:widget的大小改变.显示和隐藏事件:widget显示和隐藏.窗口事件:窗口是否为当前
2、窗口.还有一些非常见的qt事件,比如socket事件,剪贴板事件,字体改变,布局改变等等.,www.gec-edu.org,QT的事件机制,Qt 的事件和Qt中的signal不一样.后者通常用来使用widget,而前者用来实现 widget.比如一个按钮,我们使用这个按钮的时候,我们只关心他clicked()的signal,至于这个按钮如何接收处理鼠标事件,再发射这个信号,我们是不用关心的.但是如果我们要重载一个按钮的时候,我们就要面对event了.比如我们可以改变它的行为,在鼠标按键按下的时候(mouse press event)就触发clicked()的signal而不是通常在释放的(mo
3、use release event)时候.,www.gec-edu.org,QT的事件机制,事件起源:基于事件如何被产生与分发,可以把事件分为三类:*Spontaneous 事件*Posted 事件*Sent 事件,www.gec-edu.org,QT的事件机制,Spontaneous 事件,由窗口系统产生,它们被放到系统队列中,通过事件循环逐个处理。本类事件通常是window system把从系统得到的消息,比如鼠标按键,键盘按键等,放入系统的消息队列中.Qt事件循环的时候读取这些事件,转化为QEvent,再依次处理.Posted 事件,由Qt或是应用程序产生,它们被Qt组成队列,再通过事件
4、循环处理。调用QApplication:postEvent()来产生一个posted类型事件.例如:QWidget:update()函数当需要重新绘制屏幕时,程序调用update()函数其实现的原理是new出一个paintEvent,调用 QApplication:postEvent(),将其放入Qt的消息队列中,等待依次被处理.,www.gec-edu.org,QT的事件机制,Sent 事件由Qt或是应用程序产生,但它们被直接发送到目标对象。调用QApplication:sendEvent()函数来产生一个sent类型事件.sent 类型事件不会放入队列,而是直接被派发和处理,QWidget
5、:repaint()函数用的就是这种方式.,www.gec-edu.org,QT的事件机制,当我们在main()函数的末尾调用QApplication:exec()时,程序进入了Qt的事件循环事件循环如下面所示:while(!exit_was_called)while(!posted_event_queue_is_empty)process_next_posted_event();while(!spontaneous_event_queue_is_empty)process_next_spontaneous_event();while(!posted_event_queue_is_empty)
6、process_next_posted_event();,www.gec-edu.org,QT的事件机制,事件循环的处理流程:先处理Qt事件队列中的posted事件,直至为空 再处理系统消息队列中的spontaneous消息,直至为空 在处理系统消息的时候会产生新的Qt posted事件,需要对其再次进行处理 不通过事件循环sendEvent的事件派发不通过事件循环。QApplication:sendEvent()是通过调用QApplication:notify(),直接进入了事件的派发和处理环节。,www.gec-edu.org,QT的事件机制,Notify调用QApplication:se
7、ndEvent的时候,消息会立即被处理,是同步的.实际上QApplication:sendEvent()是通过调用QApplication:notify(),直接进入了事件的派发和处理环节.所有的事件都最终通过 notify 派发到相应的对象中。bool QApplication:notify(QObject*receiver,QEvent*event)它是通过调用receiver-event(event)来实现的。目标接受对象的event方法会自动接受notify传来的event事件event()会返回一个布尔值,来告诉调用者是否事件被accept或ignore,(true表示accept)
8、,从event()返回的布尔值却是用来与QApplication:notify()通讯的。,www.gec-edu.org,QT的事件机制,event()函数的处理如下所示:bool QWidget:event(QEvent*event)switch(e-type()case QEvent:KeyPress:keyPressEvent(QKeyEvent*)event);if(!(QKeyEvent*)event)-isAccepted()return false;break;case QEvent:KeyRelease:keyReleaseEvent(QKeyEvent*)event);if
9、(!(QKeyEvent*)event)-isAccepted()return false;break;.return true;,www.gec-edu.org,QT的事件机制,Close事件有点不同,调用QCloseEvent:ignore()取消了关闭操作,而accept()告诉Qt继续执行正常的关闭操作。为了避免混乱,最好是在closeEvent()的新实现中明确地进行accept()与ignore()的调用:、void MainWindow:closeEvent(QCloseEvent*event)if(userReallyWantsToQuit()event-accept();el
10、se event-ignore();,www.gec-edu.org,keyPressEvent,在空白窗体页面,重载当前窗体类的keyPressEvent方法,实现按键事件的响应。步骤一:添加头文件在form.cpp中填加void Form1:keyPressEvent(QKeyEvent*k)并实现根据不同的键值,执行不同的动作。步骤二:添加头文件在form.h 中为窗体类form1添加 void keyPressEvent(QKeyEvent*k)声明;步骤三:重新编译工程并运行测试。,www.gec-edu.org,keyPressEvent,void Form1:keyPressEv
11、ent(QKeyEvent*k)if(k-key()=Key_Left)qDebug(Leftn);.else if(k-key()=Key_Right)qDebug(Rightn);.else QWidget:keyPressEvent(k);,www.gec-edu.org,keyPressEvent,在具备子控件的复杂窗体中,重载当前窗体类的keyPressEvent方法,实现按键事件的响应。步骤一:添加头文件在form.cpp中填加void Form1:keyPressEvent(QKeyEvent*k)并实现根据不同的键值,执行不同的动作。步骤二:添加头文件在form.h 中为窗体类
12、form1添加 void keyPressEvent(QKeyEvent*k)声明;步骤三:在form.cpp中,消除子控件的焦点策略,使能方向及Tab按键功能。步骤四:重新编译工程并运行测试。,www.gec-edu.org,keyPressEvent,例如:pushButton1=new QPushButton(this,pushButton1);pushButton1-setGeometry(QRect(200,150,111,41);pushButton1-setFocusPolicy(QWidget:NoFocus);void QWidget:setFocusPolicy(Focus
13、Policy)设置这个窗口部件接收键盘焦点的方式。“focusPolicy”属性保存的是窗口部件接收键盘焦点的策略。如果窗口部件通过tab来接收键盘焦点,这个策略就是QWidget:TabFocus;如果窗口部件通过点击来接收键盘焦点,这个策略就是QWidget:ClickFocus;如果窗口部件上述两种方式都使用,是QWidget:StrongFocus;如果它不接收焦点(QWidget的默认值),是QWidget:NoFocus。,www.gec-edu.org,event,重载当前窗体类的event方法,实现针对性事件的处理与过滤效果。步骤一:在form.cpp中填加bool Form1
14、:event(QEvent*event)并实现根据不同的键值,执行不同的动作。步骤二:在form.h 中为窗体类form1添加 bool event(QEvent*event)声明;步骤三:重新编译工程并运行测试。,www.gec-edu.org,event,bool Form1:event(QEvent*event)if(event-type()=QEvent:KeyPress)QKeyEvent*keyEvent=(QKeyEvent*)event;if(keyEvent-key()=Key_A)qDebug(-cut the Key_A-n);return true;return QWi
15、dget:event(event);,www.gec-edu.org,eventFilter,Qt事件模型一个真正强大的特色是一个QObject 的实例能够管理另一个QObject 实例的事件。一个CustomerDialog的小部件。CustomerDialog 包含一系列QLineEdit.现在,我们想用空格键来代替Tab,使焦点在这些QLineEdit间切换。一个解决的方法是子类化QLineEdit,重新实现keyPressEvent(),并在keyPressEvent()里调用focusNextChild()。像下面这样:void MyLineEdit:keyPressEvent(QK
16、eyEvent*event)if(event-key()=Qt:Key_Space)focusNextChild();else QLineEdit:keyPressEvent(event);,www.gec-edu.org,eventFilter,上述做法有一个缺点。如果CustomerDialog里有很多不同的控件(比如QComboBox,QEdit,QSpinBox),我们就必须子类化这么多控件。这是一个烦琐的任务。一个更好的解决办法是:让CustomerDialog去管理他的子部件的按键事件,实现要求的行为。我们可以使用事件过滤器。一个事件过滤器的安装需要下面2个步骤:1,调用insta
17、llEventFilter()注册需要管理的对象。2,在eventFilter()里处理需要管理的对象的事件。一般,推荐在CustomerDialog的构造函数中注册被管理的对象。像下面这样:CustomerInfoDialog:CustomerInfoDialog(QWidget*parent):QDialog(parent).firstNameEdit-installEventFilter(this);lastNameEdit-installEventFilter(this);cityEdit-installEventFilter(this);phoneNumberEdit-install
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- QT 程序设计 编程 进阶 事件
![提示](https://www.31ppt.com/images/bang_tan.gif)
链接地址:https://www.31ppt.com/p-2552895.html