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);
}效果如图:

鄂公网安备 42011102003522号