Мертвые ключи не приходят в keyPressedEvent () - PullRequest
2 голосов
/ 06 октября 2010

Я использую Qt 4.3.1 (в настоящий момент я не могу обновиться) для программы, в любом случае в Windows мертвые клавиши (^, ´, `, ...) не достигают keyPressedEvent(), мне всегда приходится нажимать их дважды.

Так почему же эти мертвые ключи не приходят?Как я могу это исправить?

В MacOS все работает нормально, хотя.

Thx, eL.

Ответы [ 2 ]

2 голосов
/ 08 октября 2010

Просмотрев документацию Qt, я не уверен, что keyPressEvent должен предоставлять мертвые ключи или нет. Я на самом деле немного удивлен, что вы видите их на Mac.

Я предполагаю, что Qt выбирает ожидание событий WM_CHAR или чего-то еще перед отправкой keyPressEvent для вашего виджета. Как вы можете видеть на этой странице: 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

Если вы действительно хотите захватить нажатия клавиш замерзшей, посмотрите на подкласс QApplication и переопределите метод winEventFilter (http://doc.qt.io/qt-4.8/qcoreapplication.html#winEventFilter)). Это позволит вам захватывать события WM_DEADCHAR по мере их поступления. Затем вы можете создать KeyEvent и отправьте его виджету, который в данный момент имеет фокус.

0 голосов
/ 01 августа 2014

Предположение, что 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...