Как я могу захватить QKeySequence из QKeyEvent в зависимости от текущей раскладки клавиатуры?
Мне нужно сделать это для настройки моего приложения.
У меня есть поле QLineEdit с переопределенным методом keyPressEvent.
QKeyEvent *ke = ...
QString txt;
if(ke->modifiers() & Qt::ControlModifier)
txt += "Ctrl+";
if(ke->modifiers() & Qt::AltModifier)
txt += "Alt+";
if(ke->modifiers() & Qt::ShiftModifier)
txt += "Shift+";
if(ke->key() >= Qt::Key_0 && ke->key() <= Qt::Key_9)
txt += ('0' + ke->key() - Qt::Key_0);
else if(ke->key() >= Qt::Key_A && ke->key() <= Qt::Key_Z)
txt += ('A' + ke->key() - Qt::Key_A);
ui->hotkeyEdit->setText(txt);
Но это решение может создавать ярлыки только с английскими символами. Например, когда я использую раскладку русской клавиатуры, этот код будет отображать одну и ту же последовательность, но с английским char, помещенным на ту же клавишу клавиатуры.
Ответы
Ответ 1
Что может оказаться очень полезным, так это функция QKeySequence().toString()
.
Ниже приведена часть кода, который я использую для захвата пользовательских ярлыков. С некоторыми изменениями он может делать все, что вам нужно в вашем проекте. Надеюсь, это поможет (извините за испорченную идентификацию):
if (event->type() == QEvent::KeyPress){
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
int keyInt = keyEvent->key();
Qt::Key key = static_cast<Qt::Key>(keyInt);
if(key == Qt::Key_unknown){
qDebug() << "Unknown key from a macro probably";
return;
}
// the user have clicked just and only the special keys Ctrl, Shift, Alt, Meta.
if(key == Qt::Key_Control ||
key == Qt::Key_Shift ||
key == Qt::Key_Alt ||
key == Qt::Key_Meta)
{
qDebug() << "Single click of special key: Ctrl, Shift, Alt or Meta";
qDebug() << "New KeySequence:" << QKeySequence(keyInt).toString(QKeySequence::NativeText);
return;
}
// check for a combination of user clicks
Qt::KeyboardModifiers modifiers = keyEvent->modifiers();
QString keyText = keyEvent->text();
// if the keyText is empty than it a special key like F1, F5, ...
qDebug() << "Pressed Key:" << keyText;
QList<Qt::Key> modifiersList;
if(modifiers & Qt::ShiftModifier)
keyInt += Qt::SHIFT;
if(modifiers & Qt::ControlModifier)
keyInt += Qt::CTRL;
if(modifiers & Qt::AltModifier)
keyInt += Qt::ALT;
if(modifiers & Qt::MetaModifier)
keyInt += Qt::META;
qDebug() << "New KeySequence:" << QKeySequence(keyInt).toString(QKeySequence::NativeText);
}
Ответ 2
Если кто-то заботится о версии python решения Тихомира Долапчиева выше. Я просто перевел его, и он отлично работает. Просто отправьте для справки в будущем.
class KeySequenceEdit(QtGui.QLineEdit):
"""
This class is mainly inspired by
http://stackoverflow.com/a/6665017
"""
def __init__(self, keySequence, *args):
super(KeySequenceEdit, self).__init__(*args)
self.keySequence = keySequence
self.setKeySequence(keySequence)
def setKeySequence(self, keySequence):
self.keySequence = keySequence
self.setText(self.keySequence.toString(QtGui.QKeySequence.NativeText))
def keyPressEvent(self, e):
if e.type() == QtCore.QEvent.KeyPress:
key = e.key()
if key == QtCore.Qt.Key_unknown:
warnings.warn("Unknown key from a macro probably")
return
# the user have clicked just and only the special keys Ctrl, Shift, Alt, Meta.
if(key == QtCore.Qt.Key_Control or
key == QtCore.Qt.Key_Shift or
key == QtCore.Qt.Key_Alt or
key == QtCore.Qt.Key_Meta):
print("Single click of special key: Ctrl, Shift, Alt or Meta")
print("New KeySequence:", QtGui.QKeySequence(key).toString(QtGui.QKeySequence.NativeText))
return
# check for a combination of user clicks
modifiers = e.modifiers()
keyText = e.text()
# if the keyText is empty than it a special key like F1, F5, ...
print("Pressed Key:", keyText)
if modifiers & QtCore.Qt.ShiftModifier:
key += QtCore.Qt.SHIFT
if modifiers & QtCore.Qt.ControlModifier:
key += QtCore.Qt.CTRL
if modifiers & QtCore.Qt.AltModifier:
key += QtCore.Qt.ALT
if modifiers & QtCore.Qt.MetaModifier:
key += QtCore.Qt.META
print("New KeySequence:", QtGui.QKeySequence(key).toString(QtGui.QKeySequence.NativeText))
self.setKeySequence(QtGui.QKeySequence(key))
Ответ 3
Вы можете назначить сочетания клавиш для действий.
Вот как это сделать.
actionName->setShortcut(QKeySequence::New); //for predefined shortcuts like new, close, open..
или вы можете определить свой собственный ярлык с помощью этого
actionName->setShortcut(QKeySequence("Ctrl+N")); // sets Ctrl + N for w.e the action does
В первом случае qt автоматически определяет и назначает соответствующий ярлык для этого конкретного действия. Во втором случае вы можете выбрать свой собственный ярлык и набрать его как строку. Он автоматически анализирует и понимает.
Это позволяет избежать необходимости использования ключевых захватов для ненужных целей.
Ответ 4
Предпочитаете стандартную последовательность.
Из Проблемы с компоновкой клавиатуры:
В результате, как человекочитаемые строки, так и жестко закодированные коды клавиш могут быть проблематичными для использования при указании последовательности клавиш, которые могут использоваться на разных раскладках клавиатуры. Только использование стандартных ярлыков гарантирует, что пользователь сможет использовать ярлыки, которые разработчик предназначил.
Ответ 5
Самый простой способ:
if(event->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
qDebug() << "delete" << keyEvent->matches(QKeySequence::Delete);
qDebug() << "copy" << keyEvent->matches(QKeySequence::Copy);
qDebug() << "paste" << keyEvent->matches(QKeySequence::Paste);
}
Ответ 6
Попытка перехватить QKeySequence в keyPressEvent может работать не так, как ожидалось. И я нашел решение:
// || event->type()== QEvent::ShortcutOverride is the key point
if (event->type() == QEvent::KeyPress || event->type()== QEvent::ShortcutOverride)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->matches(QKeySequence::Save))
{
// Do save
}
}
Я надеюсь, что это помогает кому-то. :)
Ссылка: QWidget :: eventFilter() не перехватывает комбинации клавиш