从Qt中的QKeyEvent获取密钥的“名称”

时间:2014-02-13 19:49:51

标签: c++ qt key qkeyevent

是否有一种简单的方法来获取密钥的名称(所以从关键事件中获取“uparrow”而不仅仅是获取密钥代码“16777235”)?我是否必须自己制作一个关键名单?

2 个答案:

答案 0 :(得分:11)

在代码中使用人类可读的名称

您可以使用Qt::Key枚举,或将密钥作为包含QKeyEvent::text()的字符串。

来自QKeyEvent documentation

  

int QKeyEvent :: key()const

     

返回已按下或释放的键的代码。

     

有关键盘代码列表,请参阅Qt :: Key。这些代码独立于底层窗口系统。请注意,此函数不区分大写字母和非大写字母,为此目的使用text()函数(返回生成密钥的Unicode文本)。

     

...

Qt::Key是一个枚举,它将数字键ID(如QKeyEvent :: key()的返回值)映射到程序员可读的名称,如Qt::Key_Up

如果您只关心字母数字键,还可以使用QKeyEvent::text()来获取值:

  

QString QKeyEvent :: text()const

     

返回此密钥生成的Unicode文本。如果正在按下或释放修改键,例如Shift,Control,Alt和Meta,则返回的文本可以是空字符串。在这种情况下,key()将包含有效值。

     

另见Qt :: WA_KeyCompression。

向用户显示人类可读的名称

使用QKeySequence::toString()或构建自己的“好”名称表。

让人类可读的密钥名称​​向用户显示的最简单方法是使用QKeySequence::toString()

以下是一个例子:

Qt::Key key = Qt::Key_Up;
qDebug() << QKeySequence(key).toString(); // prints "Up"

如果您不喜欢QKeySequence使用的名称(例如,您想使用“向上箭头”而不是“向上”),则需要使数据表将枚举值重新映射到您的首选名称。

答案 1 :(得分:6)

另一种方法利用Qt元对象系统和对Qt名称空间中大多数枚举的内省。这适用于Qt 4和Qt 5。

// https://github.com/KubaO/stackoverflown/tree/master/questions/keyname-21764138
#include <QMetaEnum>

namespace SO {
enum KeyNameOption { KeyNameNone = 0, AppendArrow = 1 };
Q_DECLARE_FLAGS(KeyNameOptions, KeyNameOption)
}
QString keyName(int index, SO::KeyNameOptions opt = {}) {
   constexpr static auto const getEnum = [](const char *name) {
      int enumIndex = qt_getQtMetaObject()->indexOfEnumerator(name);
      return qt_getQtMetaObject()->enumerator(enumIndex);
   };
   static const auto keyEnum = getEnum("Key");
   static const auto modifierEnum = getEnum("KeyboardModifiers");

   auto name = modifierEnum.valueToKeys(index & Qt::KeyboardModifierMask);
   index &= ~Qt::KeyboardModifierMask;

   if (name == "NoModifier")
      name.clear();
   else {
      name.replace('|', '+');
      name.replace("Modifier", "");
      name.append('+');
   }

   auto keyName = keyEnum.valueToKey(index);
   if (keyName)
      name.append(keyName + 4);
   if ((opt & SO::AppendArrow) && index >= Qt::Key_Left && index <= Qt::Key_Down)
      name.append(" Arrow");
   return QLatin1String(name);
}

int main() {
   Q_ASSERT(keyName(Qt::Key_Tab) == "Tab");
   Q_ASSERT(keyName(Qt::ShiftModifier | Qt::Key_Up, SO::AppendArrow) == "Shift+Up Arrow");
   Q_ASSERT(keyName(Qt::AltModifier | Qt::Key_Down) == "Alt+Down");
}

然后,您可以在keyPressEvent中使用它,如下所示:

void MyWidget::keyPressEvent(QKeyEvent * ev) {
  qDebug() << keyName(ev->key());
}