Qt中的键盘事件,以及焦点的设置

   Qt键盘事件属于Qt事件系统,所以事件系统中所有规则对按键事件都有效。下面关注点在按键特有的部分:

focus

   一个拥有焦点(focus)的QWidget才可以接受键盘事件。有输入焦点的窗口是活动窗口或活动窗口子窗口或子子窗口等。

焦点移动的方式有以下几种:

   ·按下Tab或Shift+Tab

      注意:文本编译器(一般需要插入Tab),或者WebView(需要Tab来移动超链接焦点) 等

      Qt中,需要输入Tab的地方可以用 Ctrl+Tab 或 Ctrl+Shift+Tab 替代。

  ·点击一个QWidget

      建议:只对接受文本输入的Widget启用该功能

  ·按下键盘的快捷键

      QLabel::setBuddy(), QGroupBox,以及 QTabBar 支持

  ·使用鼠标滚轮

  ·用户移动焦点

      程序将决定被设置focus的Widget的哪一个子Widget获得焦点

   注意:如果一个 Widget 已经 grabKeyboard,所有键盘事件将发送到该Widget而不是获得焦点的Widget


focusPolicy

   一个QWidget获得焦点的方式受 focusPolicy 控制

    Qt::TabFocus:通过Tab键获得焦点

    Qt::ClickFocus:通过被单击获得焦点

    Qt::StrongFocus:可通过上面两种方式获得焦点

    Qt::NoFocus:不能通过上两种方式获得焦点(默认值),setFocus仍可使其获得焦点

keypress和keyrelease

   首先,我们要是Widget获得焦点,一般设置focusPolicy。然后要对按键进行响应,我们只需要直接重载:

    ·keyPressEvent

    ·keyReleaseEvent

  注意:

    对我们不处理的事件,要调用父类的相应事件处理函数。

    如果widget当前没有焦点,考虑到事件转发:如果其子widget有焦点,那么该widget未处理的键盘事件将被转发过来。

   有时输入焦点不在任何窗口中。这种情况发生在所有程序都是最小化的时候。这时,Windows将继续向活动窗口发送键盘消息,但是这些消息与发送给非最小化的活动窗口的键盘消息有不同的形式。


QKeyEvent

在windows下,与键盘事件有关的有8个消息:

   ·对产生可显示字符的按键组合,Windows不仅给程序发送按键消息,而且还发送字符消息

   ·有些键不产生字符,这些键包括shift键、功能键、光标移动键和特殊字符键如Insert和Delete。对于这些键,Windows只产生按键消息。

这些消息在Qt中只体现在QKeyEvent中。

   ·对字符,可通过 QKeyEvent::text() 获得

   ·其他键,QKeyEvent::key() 获得一个键值


实际程序:

   public: void keyPressEvent(QKeyEvent  *event);

   在相应键盘事件之前需要 用一个widget 进行设置   LabelComment->setFocusPolicy(Qt::StrongFocus);

void CameraShow::keyPressEvent(QKeyEvent  *event) 
{

     if(event->key()==Qt::Key_Q) 
    { 
        Pause_flag  ^= 1; 
    }

}


   在Qt中,可以使用 void QWidget::keyPressEvent ( QKeyEvent * k )来进行键盘响应,例如:

void Form1::keyPressEvent( QKeyEvent *k ) 
{ 
    if(k->key() == Key_A) 
    { 
      this->focusNextPrevChild(FALSE);//按A时焦点切换至上一部件 
    } 
    else if(k->key() == Key_D) 
    { 
      this->focusNextPrevChild(TRUE);//按D时焦点切换至下一部件 
    } 
    else if(k->key() == Key_W) 
    { 
      if(k->state() == Qt::ShiftButton) 
      { 
         this->resize(100,100);//当按下Shift+W时改变窗口大小 
      } 
    } 
}

   但是,有一些特殊的按键比如说Tab键,如果在keyPressEvent中实现则是不能成功的,因为默认Tab事件(切换焦点)被先捕获了,默认Tab和Shift+Tab事件定义在qwidget.h中,代码为:

case QEvent::KeyPress: { 
        QKeyEvent *k = (QKeyEvent *)e; 
        bool res = FALSE; 
        if ( k->key() == Key_Backtab || 
        (k->key() == Key_Tab && 
        (k->state() & ShiftButton)) ) { 
        QFocusEvent::setReason( QFocusEvent::Tab ); 
        res = focusNextPrevChild( FALSE ); 
        QFocusEvent::resetReason(); 
        } else if ( k->key() == Key_Tab ) { 
        QFocusEvent::setReason( QFocusEvent::Tab ); 
        res = focusNextPrevChild( TRUE ); 
        QFocusEvent::resetReason(); 
        } 
}

   所以我们要在之前就实现我们自己的Tab事件.实现代码如下:

bool MyWidget::event(QEvent *event)

{

if (event->type() == QEvent::KeyPress) {

QKeyEvent *ke = static_cast(event);

if (ke->key() == Qt::Key_Tab) {

// special tab handling here

return true;

}

} else if (event->type() == MyCustomEventType) {

MyCustomEvent *myEvent = static_cast(event);

// custom event handling here

return true;

}



return QWidget::event(event); }


QTextBrowser中的网址切换 

void ALMTextView::keyPressEvent(QKeyEvent* e) 
{ 
   AMDEBUG("ALMTextView special key event/n"); 
   QScrollBar *sbv = verticalScrollBar(); 
    switch( e->key() ) { 
        //case Key_Right: 
        case Key_Down: 
            if ( !selectNextPrevHref( TRUE ) ) 
            { 
                // scroll the screen down by one page 
            if (sbv->value() == sbv->maxValue()) 
            { 
                printf("asdasdasdasdasdasda/n"); 
                this->focusNextPrevChild(TRUE); 
            } 
                sbv->setValue( sbv->value() + (sbv->pageStep() >> 1) ); 
                selectNextPrevHref( TRUE ); 
            } 
            e->accept(); 
            return; 
        //case Key_Left: 
        case Key_Up: 
            if ( !selectNextPrevHref( FALSE ) ){ 
                // scroll the screen up by one page 
                if(sbv->value() == 0) 
                { 
                        printf("1234567890/n"); 
                        this->focusNextPrevChild(FALSE); 
                } 
                sbv->setValue( sbv->value() - (sbv->pageStep() >> 1) ); 
                selectNextPrevHref( FALSE ); 
            } 
            e->accept(); 
            return; 
    } 
    QTextView::keyPressEvent(e); 
}

猜你喜欢

转载自blog.csdn.net/lengyuezuixue/article/details/81055288