我正在使用Qt 4.3.1(我目前无法提升)一个程序,无论如何在Windows死键(^,',`,...)没有到达keyPressedEvent (),我总是要按两次。
那么为什么那些死钥匙不会到来?我该如何解决?
在MacOS中,一切正常。
Thx,eL。
答案 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;
}