1. 程式人生 > >Qt 焦點視窗

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