QT键盘钩子拦截按键并显示到QListWidget
项目需要拦截键盘按键并记录下来,如果只需要记录界面激活状态下的按键信息,只需要设置grabKeyboard(),就可以在virtual void
keyPressEvent(QKeyEvent *ev); virtual void keyReleaseEvent(QKeyEvent *ev);
里面读到按键信息,但是如果要在界面非激活状态也能继续,就需要设置键盘钩子。
关键代码:
#include <windows.h> HHOOK key_hook=nullptr; MacroDialog *g_MacroDlg = nullptr; DWORD g_oldKeyCode=0; DWORD g_oldKeyFlag=0; LRESULT CALLBACK KeyboardProc(int code, WPARAM wparam, LPARAM lparam) { //if(lparam>0) PKBDLLHOOKSTRUCT l=(PKBDLLHOOKSTRUCT)lparam; g_MacroDlg->OnHookKey(l->vkCode,l->flags); return CallNextHookEx(nullptr, code, wparam, lparam); } //开始记录的时候 register_key_hookvoid MacroDialog::register_key_hook() { if(key_hook) return; key_hook = SetWindowsHookEx(WH_KEYBOARD_LL,KeyboardProc,nullptr,0); } //记录完unregister_key_hookvoid MacroDialog::unregister_key_hook() { UnhookWindowsHookEx(key_hook); key_hook = nullptr; } //定义 QListWidget *m_MacroList; m_MacroList =new QListWidget(this); m_MacroList->setGeometry(276, 144, 271, 266); m_MacroList->setViewMode(QListView::ListMode); m_MacroList->setIconSize(QSize(20,20)); m_MacroList->setSpacing(1); m_MacroList->setMovement(QListView::Free); m_MacroList->setFlow(QListView::TopToBottom); //设置样式,直接在函数中设置 m_MacroList->setStyleSheet("QListWidget{border:0px solid gray; color:black; }" "QListWidget::Item:hover{background:skyblue; }" "QListWidget::item:selected{background:lightgray; color:red; }" "QListWidget::item:selected:!active{border-width:0px; background:lightgreen; }" ); void MacroDialog::OnHookKey(DWORD dwVCode, DWORD dwFlag) { //屏蔽掉按键按下重复发送的keydown的值 if(g_oldKeyCode == dwVCode && g_oldKeyFlag == dwFlag) return; g_oldKeyCode = dwVCode; g_oldKeyFlag = dwFlag; labelFocus->setFocus(); QString str; TCHAR char_str[255]; GetKeyNameText(MapVirtualKey(dwVCode,0)<<16,char_str,sizeof (char_str)); QString ret = QString::fromWCharArray(char_str); QListWidgetItem *item =new QListWidgetItem(); if(dwFlag==0) { item->setIcon(QIcon(":/skin/key_down.png")); } else { item->setIcon(QIcon(":/skin/key_up.png")); } //WillListItem为自己封装的继承于QWidget的类,目的是自己对要设置的item的Widget进行布局 WillListItem *m_Item = new WillListItem(); m_Item->SetLabel(ret); //item->setFlags(Qt::NoItemFlags); m_MacroList->addItem(item); m_MacroList->setItemWidget(item,m_Item); m_MacroList->setCurrentRow(m_MacroList->count()-1); }
效果如图: