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

}

 

還有資料:(QTextBrowser的網址切換)

http://hi.baidu.com/%D7%D4%D3%EF%B5%C4%C2%E6%CD%D5/blog/item/2758cf13d83f945df819b806.html

 

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

 

QKeyEvent類參考
QKeyEvent類用於描述鍵盤按鍵所產生的QT事件
#include<QKeyEvent>
繼承於QInpueEvent
公有函數:

QKeyEvent ( Type type, int key, Qt::KeyboardModifiers modifiers, const QString & text = QString(), bool autorep = false, ushort count = 1 )

            
int count () const
bool isAutoRepeat () const
int key () const
bool matches ( QKeySequence::StandardKey key ) const
Qt::KeyboardModifiers modifiers () const
quint32 nativeModifiers () const
quint32 nativeScanCode () const
quint32 nativeVirtualKey () const
QString text () const
相關的非成員函數:
bool operator== ( QKeyEvent * e, QKeySequence::StandardKey key )
bool operator== ( QKeySequence::StandardKey key, QKeyEvent * e )
細節描述:
QKeyEvent類用於描述鍵盤按鍵所產生的QT事件,當一個窗口具有輸入焦點時,通過鍵盤的按鍵的(敲擊/釋放)所產生的QT鍵盤事件
可以傳送給具有輸入焦點的窗口進行處理。
鍵盤QT事件包含了一些指定的接收標誌用於指出QT事件接受者是否對該事件進行處理,如果窗口不處理鍵盤的(敲擊/釋放)
可以通過調用ignore()函數予以忽略。鍵盤QT事件具有傳遞性,會傳送給父窗口及頂層窗口所構成的鏈表,一層一層的傳遞,
直到某窗口調用accept()予以接受,或者過濾直至該事件被銷燬。鍵盤QT事件對於多媒體在默認情況下總是被忽略的,
如果你的窗口要處理該事件,可以通過調用accept()函數予以接收。


可以通過調用QWidget::setEnable()函數設置某個窗口開啓/禁止接收鼠標或鍵盤事件。
QT事件句柄函數 QWidget::keyPressEvent(), QWidget::keyReleaseEvent(), QGraphicsItem::keyPressEvent() 
, QGraphicsItem::keyReleaseEvent()可以用於接收鍵盤事件。


成員函數描述:

QKeyEvent::QKeyEvent ( Type type, int key, Qt::KeyboardModifiers modifiers, const QString & text = QString(), bool autorep = false, ushort count = 1 )

初始化一個keyEvent對象。
參數type必須是QEvent::KeyPress, QEvent::KeyRelease, or QEvent::ShortcutOverride其中之一。 
參數key用於監聽QT::Key循環事件,如果key爲0則導致鍵盤事件的是一個未定義按鍵,例如,導致該鍵盤事件的可能是
連續不斷的按鍵下壓操作或者是預定義的快捷鍵。  
參數modifiers用於指出鍵盤按鍵鍵值的改變,同時給出該按鍵對應的Unicode編碼信息。
如果參數autorep爲true,函數isAutoRepeat()函數就返回true
參數count用於計算該鍵盤事件所牽扯到得按鍵的個數。


int QKeyEvent::count () const
返回鍵盤QT事件所牽扯到的按鍵的數量,如果函數text()返回不爲空,則本函數只是簡單的計算該文本字符串的長度。


bool QKeyEvent::isAutoRepeat () const
如果該鍵盤QT事件時由於一些列的自動重複的按鍵導致的則返回true,否則返回false
注意,如果導致多次疊加的按鍵組合其中一部分是自動循環形式產生的,則該函數不確定是返回true還是false。


int QKeyEvent::key () const
返回按鍵被下壓或釋放時對應的編碼值。查看Qt::Key鍵盤編碼清單,這些編碼信息都是依賴於底層操作系統的。
該函數不區分大小寫,要想知道返回的按鍵編碼所對應的按鍵是大寫還是小寫(比如A和a)可以通過調用text()函數得到。  
數字0和Qt::Key_unknown代表導致QT鍵盤事件的不是一個well_known按鍵所產生的,例如,導致該鍵盤事件的可能是一系列複雜的輸入,或者是快捷鍵,或者是被壓縮的按鍵所導致的。

bool QKeyEvent::matches ( QKeySequence::StandardKey key ) const
如果導致鍵盤QT事件的按鍵編碼值和參數key所給出的標準按鍵值匹配則返回true,否則返回false.
該函數在QT4.2中有介紹。該函數可以通過迭代方式得知當前按下的是哪一個按鍵。


Qt::KeyboardModifiers QKeyEvent::modifiers () const
鍵盤QT事件生成後直接返回導致該事件的熱鍵。提示:該函數並不總是返回很確切的結果,當用戶同時按下shift+組合鍵或者
釋放其中某一個鍵時,該函數就可能返回一個讓用戶迷惑的結果。


quint32 QKeyEvent::nativeModifiers () const
返回導致鍵盤QT事件的熱鍵編碼值,如果該事件不包含所對應的熱鍵則返回數字0.
附註:即便鍵盤事件包含擴展信息,該熱鍵也可能是爲0的。
該函數在QT4.2中有介紹。


quint32 QKeyEvent::nativeScanCode () const
返回導致該鍵盤QT事件的掃描碼,如果敢事件不包含所對應的掃描碼則返回數字0.
附註:即便鍵盤事件包含擴展信息,該掃描碼也可能是爲0的。
附註:在Mac OS/X 系統上該函數式無效的,因爲沒有辦法從Cocoa或者Carbon中獲取掃描碼,該函數通常返回1,或者當包含擴展信息時返回0.
該函數在QT4.2中有介紹


quint32 QKeyEvent::nativeVirtualKey () const
返回導致鍵盤QT事件的虛擬鍵或者字符碼,如果該鍵盤事件沒有包含該按鍵的編碼則返回0.
附註:即便鍵盤事件包含擴展信息,該虛擬鍵也可能是爲0的。 
該函數在QT4.2中有介紹


QString QKeyEvent::text () const
返回導致的鍵盤事件的Unicode字符編碼信息,當導致鍵盤事件的原因是由熱鍵比如Shift, Control, Alt等的下壓或者釋放,
則該函數返回的字符可以爲空值。在這種情況下函數key()可以返回一個有效值。


相關的非成員函數:
bool operator== ( QKeyEvent * e, QKeySequence::StandardKey key )
如果參數e和參數key類型匹配且相等則返回true
等同於函數 e->matches(key).


bool operator== ( QKeySequence::StandardKey key, QKeyEvent * e )
如果參數e和參數key類型匹配且相等則返回true
等同於函數 e->matches(key).

 

http://blog.csdn.NET/zzk197/article/details/7383715

http://blog.csdn.Net/free_program_1314/article/details/7681456

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