@ksming的回答很好,但不完整,并且存在一个可能未处理的特殊情况。在Windows和OSX上,当拖动、调整大小或失去焦点时,可能无法接收到键盘事件。这可能导致地图处于不一致的状态。
处理这种情况的最佳方法是在检测到这些事件时重置地图,使用QEvent::NonClientAreaMouseButtonPress。
具体来说,
1. 当按下键时,在地图中记录此信息。
2. 当释放键时,从地图中删除它。
3. 当窗口被拖动时,清除地图 - 这样可以保持一致的状态,因为在那段时间内你不可能知道状态。
缺点是你无法在拖动或调整大小时处理事件,但我认为在大多数情况下这应该没问题。当用户完成对窗口的处理后,让他们自己处理这些事件。另一种选择是以平台相关的方式处理键盘事件。
需要注意的是,在OSX上,似乎必须从应用程序级别监听NonClientAreaMouseButtonPress。也就是说,像在Windows上那样,小部件不会接收到此事件。
class KeyPressFilter : public QObject {
public:
bool eventFilter(QObject* aObject, QEvent* aEvent) final {
if (aEvent->type() == QEvent::NonClientAreaMouseButtonPress) {
}
return QObject::eventFilter(aObject, aEvent);
}
};
{
QApplication myApplication{...};
KeyPressFilter myKeyFilter;
myApplication.installEventFilter(&myKeyFilter);
myApplication.exec();
}
类似这样的东西应该可以工作
你可能还想处理QEvent::WindowDeactivate
,原因完全相同(如果在处理按键时焦点发生变化)。
关于这个问题的讨论链接可以在这里找到(截至QT 6.5.1版本为准)。