死键未到达keyPressedEvent()

时间:2010-10-06 11:48:58

标签: qt event-handling keyboard

我正在使用Qt 4.3.1(我目前无法提升)一个程序,无论如何在Windows死键(^,',`,...)没有到达keyPressedEvent (),我总是要按两次。

那么为什么那些死钥匙不会到来?我该如何解决?

在MacOS中,一切正常。

Thx,eL。

2 个答案:

答案 0 :(得分:2)

在查看Qt文档后,我不确定keyPressEvent是否应该提供死键。我真的很惊讶你在Mac上看到它们。

我猜测Qt在为您的小部件发送keyPressEvent之前选择等待WM_CHAR事件等。正如您在此页面中看到的那样:http://msdn.microsoft.com/en-us/library/ms646267(VS.85).aspx#_win32_Dead_Character_Messages当用户按下死键后跟真实键时,键事件的顺序为:

WM_KEYDOWN
WM_DEADCHAR
WM_KEYUP
WM_KEYDOWN
WM_CHAR
WM_KEYUP

如果你真的想要捕获deadchar按键,请查看子类化QApplication并重写winEventFilter(http://doc.qt.io/qt-4.8/qcoreapplication.html#winEventFilter)方法。这将允许您在进入时捕获WM_DEADCHAR事件。然后,您可以创建KeyEvent并将其分派给当前具有焦点的窗口小部件。

答案 1 :(得分:0)

Qt等待WM_CHAR事件的猜测是错误的。在处理WM_KEYDOWN事件时,Qt在消息队列中查找WM_DEADCHAR消息。如果有这样的消息,Qt会绕过正常的WM_KEYDOWN处理。如果您想要接收死键的QKeyEvent,您应该从WM_DEADCHAR消息中清除消息队列。写一些像这样的代码:

bool TEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
 if(eventType=="windows_generic_MSG")
 { 
  MSG *msg=static_cast<MSG*>(message);
  MSG peekedMsg;
  switch(msg->message)
  {
   case WM_KEYDOWN:
   case WM_SYSKEYDOWN:
   PeekMessage(&peekedMsg, msg->hwnd, WM_DEADCHAR, WM_DEADCHAR, PM_REMOVE); 
   case WM_CHAR:
   case WM_DEADCHAR:
   if(msg->lParam&0x40000000) //message is repeated via the key holding down
   return 1;
  }
 }
 return 0;
}