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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章