QT如何捕获全局的键盘事件?

QT如何捕获全局的键盘事件

方法一:继承QApplication,并重载notify()函数

Qt是用QApplication::notify()函数来分发事件的想要在任何事件过滤器查看任何事件之前先得到这些事件重载这个函数是唯一的办法通常来说事件过滤器更好用一些, 因为不需要去继承QApplication而且可以给QApplication对象安装任意个数的事件过滤器相比之下 notify()函数只有一个

代码如下:

class MyApplication : public QApplication

{

public:

     MyApplication(int&argc,char **argv);

     bool notify(QObject*, QEvent *);

     void setWindowInstance(MainWindow*wnd);

private:

     MainWindow* window;//保存一个你窗体的指针

};

 

MyApplication::MyApplication(int &argc,char **argv):

QApplication(argc,argv),window(0)

{

 

}

 

void MyApplication::setWindowInstance(MainWindow *wnd)

{

     window = wnd;

}

 

bool MyApplication::notify(QObject *obj, QEvent *e)

{

     const QMetaObject* objMeta = obj->metaObject();
     QString clName = objMeta->className();

     if((e->type() == QEvent::KeyPress) && (clName != "QLineEdit"))
     {

          if(window)

          {

                QKeyEvent*keyEvent = static_cast<QKeyEvent *>(e);

                window->keyPress(keyEvent);

          }

     }

     return QApplication::notify(obj,e);

}

 

注:

Qt的事件和Qt中的signal不一样后者通常用来"使用"widget, 而前者用来"实现" widget. 比如一个按钮我们使用这个按钮的时候我们只关心他clicked()signal, 至于这个按钮如何接收处理鼠标事件,再发射这个信号,我们是不用关心的但是如果我们要重载一个按钮的时候,我们就要面对event比如我们可以改变它的行为,在鼠标按键按下的时候(mouse press event) 就触发clicked()signal而不是通常在释放的( mouse release event)时候.

 

事件的产生

事件的两种来源:

       一种是系统产生的;通常是window system把从系统得到的消息,比如鼠标按键,键盘按键等放入系统的消息队列中. Qt事件循环的时候读取这些事件,转化为QEvent,再依次处理.

       一种是由Qt应用程序程序自身产生的.程序产生事件有两种方式一种是调用QApplication::postEvent(). 例如QWidget::update()函数,当需要重新绘制屏幕时,程序调用update()函数,new出来一个paintEvent,调用QApplication::postEvent(),将其放入Qt的消息队列中,等待依次被处理.另一种方式是调用sendEvent()函数这时候事件不会放入队列而是直接被派发和处理, QWidget::repaint()函数用的就是这种方式.

 

事件的派发和处理

首先说明Qt中事件过滤器的概念事件过滤器是Qt中一个独特的事件处理机制功能强大而且使用起来灵活方便通过它可以让一个对象侦听拦截另外一个对象的事件事件过滤器是这样实现的在所有Qt对象的基类: QObject中有一个类型为QObjectList的成员变量,名字为eventFilters,当某个QObjec (qobjA)给另一个QObject (qobjB)安装了事件过滤器之后, qobjB会把qobjA的指针保存在eventFilters.qobjB处理事件之前,会先去检查eventFilters列表如果非空就先调用列表中对象的eventFilter()函数.一个对象可以给多个对象安装过滤器同样一个对象能同时被安装多个过滤器在事件到达之后这些过滤器以安装次序的反序被调用事件过滤器函数( eventFilter() ) 返回值是bool如果返回true, 则表示该事件已经被处理完毕, Qt将直接返回进行下一事件的处理如果返回false, 事件将接着被送往剩下的事件过滤器或是目标对象进行处理.

Qt,事件的派发是从QApplication::notify() 开始的因为QAppliction也是继承自QObject, 所以先检查QAppliation对象如果有事件过滤器安装在qApp先调用这些事件过滤器接下来QApplication::notify() 会过滤或合并一些事件(比如失效widget的鼠标事件会被过滤掉而同一区域重复的绘图事件会被合并). 之后,事件被送到reciver::event() 处理.

同样reciver::event()先检查有无事件过滤器安装在reciever若有则调用之接下来,根据QEvent的类型调用相应的特定事件处理函数一些常见的事件都有特定事件处理函数比如:mousePressEvent(), focusOutEvent(),  resizeEvent(),paintEvent(), resizeEvent()等等在实际应用中,经常需要重载这些特定事件处理函数在处理事件但对于那些不常见的事件是没有相对应的特定事件处理函数的如果要处理这些事件就需要使用别的办法比如重载event() 函数或是安装事件过滤器.

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值