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); 
}

--------------------- 本文来自 冷月醉雪 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/lengyuezuixue/article/details/81055288?utm_source=copy

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值