zoukankan      html  css  js  c++  java
  • Qt 中如何捕获窗口停用和激活的消息

    最近一直在用Qt做一个简单的俄罗斯方块的游戏,由于要实现一个暂停游戏的功能,就是当鼠标移出正在运行的游戏,点击电脑桌面上的其他位置时,这个时候游戏暂停。在这里把实现过程简单的记录一下,作为一个学习笔记,如果有什么错误之处,还希望大家指出,共同提高,谢谢!
    刚开始的时候,我很自然的想到要实现这个功能,只要重载一下下面的这个函数:

    [cpp] view plaincopy
     
    1. void QWidget::focusOutEvent ( QFocusEvent * event )   [virtual protected]  


    我赶紧的测试一下,但是发现并没有实现我想要得功能,而且当我的鼠标离开正在运行的游戏,点击电脑桌面上其他的位置时,focusOutEvent这个事件并没有被触发(重载的时候,我在这个函数里面加啦一句打印的,如果触发啦这个事件,会有一个打印的)。
    在网上搜索啦一些资料,发现这其实是基础知识不扎实的表现,我们先来认识与区别一下前景窗口(Foreground Window),活动窗口(Active) 。

    任何一个时候,我们的Windows桌面上总有一个最前台的窗口,其实说简单的,就是标题栏变成深蓝色的那个窗口,仅此一个,这个窗口就是前景窗口(Foreground Window),其他窗口就是后台窗口(Background Window)。那创建前景窗口的线程就是前景线程(Foreground Thread),这个线程并不一定就是应用程序的主线程。
    线程内部会维护当前自己的活动窗口(Active Window)和焦点窗口(Focus Window), 焦点窗口其实只是窗口的一个属性,其实就是“焦点状态”是窗口的一个属性,而焦点窗口的顶层窗口就是活动窗口,举个例子:一个对话框中有一个按钮,当按钮 获得焦点的时候,那此按钮就是焦点窗口,则包含此按钮的对话框就是活动窗口,若出现窗口嵌套的情况,则最根的那个窗口才是活动窗口。(以上文字引自开头的文章 )

    通过上面的文字我们可以看出,焦点窗口是一个局部的概念,我所要实现的点击桌面上其他位置时其实是让当前活动窗口(Active)变为不不活动的窗口。所以通过上面的重载focusOutEvent这个函数,是绝对不可能达到要求的。
    又仔细搜寻啦Qt文档,发现里面有
    QEvent::WindowDeactivate
    QEvent::WindowActivate
    这样两个QEvent::Type枚举类型的值,这正好是我们要的活动窗口(Active)与不不活动的窗口事件切换的标签,Qt中没有留出这样的事件的接口,我们通过重载下面这个函数:
    bool QObject::eventFilter ( QObject * watched, QEvent * event )   [virtual]
    安装一个事件过滤器,来处理。
     

    [cpp] view plaincopy
     
    1. class MyWidget : QWidget //  
    2. {  
    3. prviate:  
    4.   
    5. public:  
    6.    MyWindget();      
    7. protected:  
    8.    bool eventFilter(QObject *o, QEvent *e);//事件过滤器  
    9. }  
    10.   
    11. MyWidget::MyWidget()  
    12. {  
    13.    QWidget::installEventFilter(this);//为这个窗口安装过滤器  
    14. }  
    15.   
    16. 在类中重载eventFilter函数:  
    17.   
    18. bool MyWidget::eventFilter(QObject *watched, QEvent *event)  
    19. {  
    20.     if( watched == this )  
    21.     {  
    22.         //窗口停用,变为不活动的窗口  
    23.         if(QEvent::WindowDeactivate == event->type())  
    24.         {  
    25.             //  
    26.             //DEBUGP( "eventFilter" ) ;  
    27.             hide();  //或者关闭窗口,加入自己的操作.  
    28.             return true ;  
    29.         }  
    30.         else  
    31.         {  
    32.             return false ;  
    33.         }  
    34.     }  
    35.     return false ;  
    36. }  


    再次进行测试,发现完美实现我想要得功能!很happy!

    参考:http://blog.csdn.net/xj178926426/article/details/7188246

  • 相关阅读:
    路径变量@PathVariable/请求参数@RequestParam的绑定以及@RequestBody
    JSR303后端校验详细笔记
    创建ssm项目步骤
    利用 R 绘制拟合曲线
    在 Linux 中将 Caps 根据是否为修饰键分别映射到 esc 和 Ctrl
    Master Transcription Factors and Mediator Establish Super-Enhancers at Key Cell Identity Genes
    Genomic Evidence for Complex Domestication History of the Cultivated Tomato in Latin America
    Variation Revealed by SNP Genotyping and Morphology Provides Insight into the Origin of the Tomato
    The genetic, developmental, and molecular bases of fruit size and shape variation in tomato
    微信支付jsapi
  • 原文地址:https://www.cnblogs.com/findumars/p/4780392.html
Copyright © 2011-2022 走看看