Recently I am working on a QT project, which requires identifying keyboard input keys to generate shortcut keys. There is a class QKeySequenceEdit in QT. Using this, you can directly obtain keyboard input. However, if you want to filter out the keys you do not want to recognize, you must rewrite it. ThekeyPressEvent(QKeyEvent *e) function.
At first I used this control to read shortcut keys, but due to other requirements I changed to using the QlineEdit control and rewritten its keyPressEvent(QKeyEvent * e) function, which simply implements reading keyboard input shortcut keys, is actually similar to QKeySequenceEdit. After all, the source code of the latter is encapsulated using the former. Due to project requirements, I used QlineEdit. Here’s how I got filtered keyboard input and the problems I encountered and how I solved it.
head File
#ifndef MYKEYKUAIJIE_H #defineMYKEYKUAIJIE_H #include <QKeySequenceEdit> #include <QLineEdit> #include <QKeyEvent> #include <QDebug> #include <QTimer> class Mykeykuaijie : public QLineEdit { Q_OBJECT public: explicit Mykeykuaijie(QWidget *parent = nullptr); signals: void send_text(QString text); private: void keyPressEvent(QKeyEvent *event) override; bool isValidKey(int key, Qt::KeyboardModifiers modifiers); }; #endif // MYKEYKUAIJIE_H
The bool isValidKey(int key, Qt::KeyboardModifiers modifiers) function implements filtering keyboard input
Source File
#include "mykeykuaijie.h" Mykeykuaijie::Mykeykuaijie(QWidget *parent) :QLineEdit(parent) { //installEventFilter(this) CtrlShift = false; } void Mykeykuaijie::keyPressEvent(QKeyEvent *event) { // Get the currently pressed key and modifier key int key = event->key(); Qt::KeyboardModifiers modifiers = event->modifiers(); QString KJtext; if (isValidKey(key, modifiers)) { //If it is not a letter or F1-F12, it will not be set. if((key >= Qt::Key_A & amp; & amp; key <= Qt::Key_Z) || (key >= Qt::Key_F1 & amp; & amp; key <= Qt::Key_F12)){ KJtext = QKeySequence(key | modifiers).toString(); setText(KJtext); emit send_text(QKeySequence(key | modifiers).toString()); } } // Not a valid key combination, reset the key sequence else { event->ignore(); setText(KJtext); } } bool Mykeykuaijie::isValidKey(int key, Qt::KeyboardModifiers modifiers) { // Only allow Alt, Ctrl, Shift and letter keys and F1 to F12 as key combinations return modifiers == Qt::ControlModifier || modifiers == Qt::ShiftModifier || modifiers == Qt::AltModifier || (key >= Qt::Key_A & amp; & amp; key <= Qt::Key_Z) || (key >= Qt::Key_F1 & amp; & amp; key <= Qt::Key_F12); }
I only recognize single letters, single F1-F12, Ctrl and the three modifier keys Alt and Shft combined with letters and F1-12
The above steps can basically identify the combination I want to identify under Windows.
but! ! !
My QT project is to be run in a Linux environment, so based on the above writing method, some key combinations cannot be recognized. These key combinations are:
1. Ctrl + F1-11
Reason: pressing Ctrl and then pressing F1-11 will recognize F1-11 as F25-35, which will naturally be filtered out by my filter function. Even if it is not filtered, the display will be incorrect.
solve:
// If you press Ctrl + F1-F11 if (event->modifiers() == Qt::ControlModifier & amp; & amp; event->key() >= Qt::Key_F25 & amp; & amp; event->key() <= Qt::Key_F35) { // Recognize it as F1-F12 int fKey = event->key() - Qt::Key_F25 + Qt::Key_F1; QKeyEvent newEvent(event->type(), fKey, event->modifiers(), event->text(), event->isAutoRepeat(), event->count()); Mykeykuaijie::keyPressEvent(& amp;newEvent); }
Just remove the identified F25-35 and re-add F1-11.
2. Shift + F1-12
Reference 1.
3. Ctrl + Shift + letter
This is a bit difficult, for the following reasons:
I added the printing information and found that when I pressed Ctrl + Shift on the keyboard, event->modifiers() included Qt::ControlModifier and Qt::ShiftModifier, but when I pressed the letter again, shift was blocked and event ->modifiers() only contains Qt::ControlModifier. I came up with a somewhat bizarre solution by referring to solutions on the Internet and thinking about it day and night.
Code first
// Determine whether the Ctrl, Shift and Alt keys are pressed bool ctrlPressed = event->modifiers() & amp; Qt::ControlModifier; bool shiftPressed = event->modifiers() & amp; Qt::ShiftModifier; //Solve that Ctrl + Shift + letters will block Shift and only display Ctrl + letters if (ctrlPressed) { if(shiftPressed){ add(); //Determine whether the current shift key is pressed } add2(); //Because each time a key is pressed, the keyPressEvent function will be re-entered, so CtrlShift is used to determine whether shift was pressed before pressing the letter key. if(event->key() >= Qt::Key_A & amp; & amp; event->key() <= Qt::Key_Z & amp; & amp; CtrlShift2){ Qt::KeyboardModifiers modifiers2 = Qt::ShiftModifier | event->modifiers(); QString KJtext2 = QKeySequence(key | modifiers2).toString(); qDebug()<<KJtext2; setText(KJtext2); emit send_text(KJtext2); } } void Mykeykuaijie::add(){ CtrlShift = true; } void Mykeykuaijie::add2(){ if(CtrlShift == true){ CtrlShift2 = true; }else{ CtrlShift2 = false; } }
That is, after pressing Ctrl, first determine whether shift is still pressed, and then manually add Qt::ShiftModifier back to event->modifiers(). Since the keyPressEvent function is triggered every time a key is pressed, the add add2 functions I added are to prevent my bool from being reset when the letter key is pressed.
4. Alt + Shift + letter
Same as 3.
5. Ctrl + Alt + F1-12
This QT is really cruel. After pressing Ctrl + Alt and then pressing F1-12, nothing happens, so I can’t solve it hahaha
Finally, the writing above may be a bit messy. This is the detailed code of the source file for reference (creation is not easy, hahaha)
#include "mykeykuaijie.h" Mykeykuaijie::Mykeykuaijie(QWidget *parent) :QLineEdit(parent) { //installEventFilter(this) CtrlShift = false; } void Mykeykuaijie::keyPressEvent(QKeyEvent *event) { // Get the currently pressed key and modifier key int key = event->key(); Qt::KeyboardModifiers modifiers = event->modifiers(); QString KJtext; qDebug()<<modifiers<<"****"<<event; // Check if it is a valid key combination // If Shift + F1-F12 is pressed if (event->modifiers() == Qt::ShiftModifier & amp; & amp; event->key() >= Qt::Key_F13 & amp; & amp; event->key() <= Qt::Key_F24 ) { // Recognize it as F1-F12 int fKey = event->key() - Qt::Key_F13 + Qt::Key_F1; QKeyEvent newEvent(event->type(), fKey, event->modifiers(), event->text(), event->isAutoRepeat(), event->count()); Mykeykuaijie::keyPressEvent(& amp;newEvent); } // If you press Ctrl + F1-F11 if (event->modifiers() == Qt::ControlModifier & amp; & amp; event->key() >= Qt::Key_F25 & amp; & amp; event->key() <= Qt::Key_F35 ) { // Recognize it as F1-F12 int fKey = event->key() - Qt::Key_F25 + Qt::Key_F1; QKeyEvent newEvent(event->type(), fKey, event->modifiers(), event->text(), event->isAutoRepeat(), event->count()); Mykeykuaijie::keyPressEvent(& amp;newEvent); } /* QKeyEvent newEvent(event->type(), event->key(), modifiers2, event->text(), event->isAutoRepeat(), event->count()); Mykeykuaijie::keyPressEvent(& amp;newEvent); */ \t // Determine whether the Ctrl, Shift and Alt keys are pressed bool ctrlPressed = event->modifiers() & amp; Qt::ControlModifier; bool shiftPressed = event->modifiers() & amp; Qt::ShiftModifier; bool altPressed = event->modifiers() & amp; Qt::AltModifier; //Solve that Ctrl + Shift + letters will block Shift and only display Ctrl + letters if (ctrlPressed) { if(shiftPressed){ add(); //Determine whether the current shift key is pressed } add2(); //Because each time a key is pressed, the keyPressEvent function will be re-entered, so CtrlShift is used to determine whether shift was pressed before pressing the letter key. if(event->key() >= Qt::Key_A & amp; & amp; event->key() <= Qt::Key_Z & amp; & amp; CtrlShift2){ Qt::KeyboardModifiers modifiers2 = Qt::ShiftModifier | event->modifiers(); QString KJtext2 = QKeySequence(key | modifiers2).toString(); qDebug()<<KJtext2; setText(KJtext2); emit send_text(KJtext2); } } //Solve the problem that Alt + Shift + letters will block Shift and only display Alt + letters if(altPressed) { if(shiftPressed){ add(); } add2(); if(event->key() >= Qt::Key_A & amp; & amp; event->key() <= Qt::Key_Z & amp; & amp; CtrlShift2){ Qt::KeyboardModifiers modifiers2 = event->modifiers() | Qt::ShiftModifier; QString KJtext2 = QKeySequence(key | modifiers2).toString(); qDebug()<<KJtext2; setText(KJtext2); emit send_text(KJtext2); } } if (isValidKey(key, modifiers)) { //The situation of Ctrl + Shift + letters must be blocked here, otherwise Ctrl + Shift + letters will block Shift and only display Ctrl + letters. if (ctrlPressed){ if(shiftPressed){ add(); } add2(); if(event->key() >= Qt::Key_A & amp; & amp; event->key() <= Qt::Key_Z){ if(CtrlShift2){ return; } } } //The situation of Alt + Shift + letters must be blocked here if (altPressed){ if(shiftPressed){ add(); } add2(); if(event->key() >= Qt::Key_A & amp; & amp; event->key() <= Qt::Key_Z){ if(CtrlShift2){ return; } } } //Key, so that Ctrl + letter can be triggered normally CtrlShift = false; //If it is not a letter or F1-F12, it will not be set. if((key >= Qt::Key_A & amp; & amp; key <= Qt::Key_Z) || (key >= Qt::Key_F1 & amp; & amp; key <= Qt::Key_F12)){ KJtext = QKeySequence(key | modifiers).toString(); setText(KJtext); emit send_text(QKeySequence(key | modifiers).toString()); } } // Not a valid key combination, reset the key sequence else { event->ignore(); setText(KJtext); } \t \t } bool Mykeykuaijie::isValidKey(int key, Qt::KeyboardModifiers modifiers) { // Only allow Alt, Ctrl, Shift and letter keys and F1 to F12 as key combinations return modifiers == Qt::ControlModifier || modifiers == Qt::ShiftModifier || modifiers == Qt::AltModifier || (key >= Qt::Key_A & amp; & amp; key <= Qt::Key_Z) || (key >= Qt::Key_F1 & amp; & amp; key <= Qt::Key_F12); } void Mykeykuaijie::add(){ CtrlShift = true; } void Mykeykuaijie::add2(){ if(CtrlShift == true){ CtrlShift2 = true; }else{ CtrlShift2 = false; } }
The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. CS entry skill treeLinux introductionFirst introduction to Linux37867 people are learning the system