How can I capture QKeySequence from QKeyEvent depending on current keyboard layout?

后端 未结 7 1453
一向
一向 2020-12-09 12:05

I need to do this for configuring my application. I have QLineEdit field with reimplemented keyPressEvent method.

QKeyEvent *ke = ...
QString txt;

if(ke->         


        
相关标签:
7条回答
  • 2020-12-09 12:25

    What you might find very useful is the function QKeySequence().toString().

    The following is a part of a code that I use to capture User Defined Shortcuts. With some modifications it can do whatever you need in your project. Hope it helps (sorry for the crapped identation):

    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's 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); 
    }
    
    0 讨论(0)
  • 2020-12-09 12:26

    You can assign keyboard shortcuts to actions.

    Here are someways to do it.

    actionName->setShortcut(QKeySequence::New); //for predefined shortcuts like new, close, open..
    

    or you can define your own shortcut with this

    actionName->setShortcut(QKeySequence("Ctrl+N")); // sets Ctrl + N for w.e the action does
    

    In the first case qt automatically detects and assigns the appropriate shortcut for that particular action. In the second case, you can pick your own desired shortcut and type it as string. It automatically parses it and understands.

    This avoids the need for using key captures for unnecessary purposes.

    0 讨论(0)
  • 2020-12-09 12:27

    Prefer a standard seqence.

    From the Keyboard Layout Issues:

    As a result, both human-readable strings and hard-coded key codes can both be problematic to use when specifying a key sequence that can be used on a variety of different keyboard layouts. Only the use of standard shortcuts guarantees that the user will be able to use the shortcuts that the developer intended.

    0 讨论(0)
  • 2020-12-09 12:30

    simpliest way is:

    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);
    }
    
    0 讨论(0)
  • 2020-12-09 12:35

    If someone cares for the python version of the solution of Tihomir Dolapchiev above. I just translated it and it works great. Just posting for future reference.

    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's 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))
    
    0 讨论(0)
  • 2020-12-09 12:36

    in case Qt users want it for Qml, here's how I did it.

    There are however a few extra features that you might not want. I'll leave the code here and let users adapt.

    TextField {
        Layout.fillWidth: true
        placeholderText: qsTr("Shortcut")
        text: shortcut
        onTextChanged: myModel.setPropertyAndUpdate(index, "shortcut", text, this)
    
        property var modifiers: ({ 0x02000000: "Shift", 0x04000000: "Ctrl", 0x08000000: "Alt", 0x10000000: "Meta", 0x20000000: "Keypad", 0x40000000: "GroupSwitch" })
        property var keys: ({
            0x01000000: "Escape", 0x01000001: "Tab", 0x01000002: "Backtab", 0x01000003: "Backspace", 0x01000004: "Return", 0x01000005: "Enter", 0x01000006: "Insert", 0x01000007: "Delete", 0x01000008: "Pause", 0x01000009: "Print", 0x0100000a: "SysReq", 0x0100000b: "Clear", 0x01000010: "Home", 0x01000011: "End", 0x01000012: "Left", 0x01000013: "Up", 0x01000014: "Right", 0x01000015: "Down", 0x01000016: "PageUp", 0x01000017: "PageDown", 0x01000020: "Shift", 0x01000021: "Control", 0x01000022: "Meta", 0x01000023: "Alt", 0x01001103: "AltGr", 0x01000024: "CapsLock", 0x01000025: "NumLock", 0x01000026: "ScrollLock", 0x01000030: "F1", 0x01000031: "F2", 0x01000032: "F3", 0x01000033: "F4", 0x01000034: "F5", 0x01000035: "F6", 0x01000036: "F7", 0x01000037: "F8", 0x01000038: "F9", 0x01000039: "F10", 0x0100003a: "F11", 0x0100003b: "F12", 0x0100003c: "F13", 0x0100003d: "F14", 0x0100003e: "F15", 0x0100003f: "F16", 0x01000040: "F17", 0x01000041: "F18", 0x01000042: "F19", 0x01000043: "F20", 0x01000044: "F21", 0x01000045: "F22", 0x01000046: "F23", 0x01000047: "F24", 0x01000048: "F25", 0x01000049: "F26", 0x0100004a: "F27", 0x0100004b: "F28", 0x0100004c: "F29", 0x0100004d: "F30", 0x0100004e: "F31", 0x0100004f: "F32", 0x01000050: "F33", 0x01000051: "F34", 0x01000052: "F35", 0x01000053: "Super_L", 0x01000054: "Super_R", 0x01000055: "Menu", 0x01000056: "Hyper_L", 0x01000057: "Hyper_R", 0x01000058: "Help", 0x01000059: "Direction_L", 0x01000060: "Direction_R", 0x20: "Space", 0x21: "Exclam", 0x22: "QuoteDbl", 0x23: "NumberSign", 0x24: "Dollar", 0x25: "Percent", 0x26: "Ampersand", 0x27: "Apostrophe", 0x28: "ParenLeft", 0x29: "ParenRight", 0x2a: "Asterisk", 0x2b: "Plus", 0x2c: "Comma", 0x2d: "Minus", 0x2e: "Period", 0x2f: "Slash", 0x30: "0", 0x31: "1", 0x32: "2", 0x33: "3", 0x34: "4", 0x35: "5", 0x36: "6", 0x37: "7", 0x38: "8", 0x39: "9", 0x3a: "Colon", 0x3b: "Semicolon", 0x3c: "Less", 0x3d: "Equal", 0x3e: "Greater", 0x3f: "Question", 0x40: "At", 0x41: "A", 0x42: "B", 0x43: "C", 0x44: "D", 0x45: "E", 0x46: "F", 0x47: "G", 0x48: "H", 0x49: "I", 0x4a: "J", 0x4b: "K", 0x4c: "L", 0x4d: "M", 0x4e: "N", 0x4f: "O", 0x50: "P", 0x51: "Q", 0x52: "R", 0x53: "S", 0x54: "T", 0x55: "U", 0x56: "V", 0x57: "W", 0x58: "X", 0x59: "Y", 0x5a: "Z", 0x5b: "BracketLeft", 0x5c: "Backslash", 0x5d: "BracketRight", 0x5e: "AsciiCircum", 0x5f: "Underscore", 0x60: "QuoteLeft", 0x7b: "BraceLeft", 0x7c: "Bar", 0x7d: "BraceRight", 0x7e: "AsciiTilde", 0x0a0: "nobreakspace", 0x0a1: "exclamdown", 0x0a2: "cent", 0x0a3: "sterling", 0x0a4: "currency", 0x0a5: "yen", 0x0a6: "brokenbar", 0x0a7: "section", 0x0a8: "diaeresis", 0x0a9: "copyright", 0x0aa: "ordfeminine", 0x0ab: "guillemotleft", 0x0ac: "notsign", 0x0ad: "hyphen", 0x0ae: "registered", 0x0af: "macron", 0x0b0: "degree", 0x0b1: "plusminus", 0x0b2: "twosuperior", 0x0b3: "threesuperior", 0x0b4: "acute", 0x0b5: "mu", 0x0b6: "paragraph", 0x0b7: "periodcentered", 0x0b8: "cedilla", 0x0b9: "onesuperior", 0x0ba: "masculine", 0x0bb: "guillemotright", 0x0bc: "onequarter", 0x0bd: "onehalf", 0x0be: "threequarters", 0x0bf: "questiondown", 0x0c0: "Agrave", 0x0c1: "Aacute", 0x0c2: "Acircumflex", 0x0c3: "Atilde", 0x0c4: "Adiaeresis", 0x0c5: "Aring", 0x0c6: "AE", 0x0c7: "Ccedilla", 0x0c8: "Egrave", 0x0c9: "Eacute", 0x0ca: "Ecircumflex", 0x0cb: "Ediaeresis", 0x0cc: "Igrave", 0x0cd: "Iacute", 0x0ce: "Icircumflex", 0x0cf: "Idiaeresis", 0x0d0: "ETH", 0x0d1: "Ntilde", 0x0d2: "Ograve", 0x0d3: "Oacute", 0x0d4: "Ocircumflex", 0x0d5: "Otilde", 0x0d6: "Odiaeresis", 0x0d7: "multiply", 0x0d8: "Ooblique", 0x0d9: "Ugrave", 0x0da: "Uacute", 0x0db: "Ucircumflex", 0x0dc: "Udiaeresis", 0x0dd: "Yacute", 0x0de: "THORN", 0x0df: "ssharp", 0x0f7: "division", 0x0ff: "ydiaeresis", 0x01001120: "Multi_key", 0x01001137: "Codeinput", 0x0100113c: "SingleCandidate", 0x0100113d: "MultipleCandidate", 0x0100113e: "PreviousCandidate", 0x0100117e: "Mode_switch", 0x01001121: "Kanji", 0x01001122: "Muhenkan", 0x01001123: "Henkan", 0x01001124: "Romaji", 0x01001125: "Hiragana", 0x01001126: "Katakana", 0x01001127: "Hiragana_Katakana", 0x01001128: "Zenkaku", 0x01001129: "Hankaku", 0x0100112a: "Zenkaku_Hankaku", 0x0100112b: "Touroku", 0x0100112c: "Massyo", 0x0100112d: "Kana_Lock", 0x0100112e: "Kana_Shift", 0x0100112f: "Eisu_Shift", 0x01001130: "Eisu_toggle", 0x01001131: "Hangul", 0x01001132: "Hangul_Start", 0x01001133: "Hangul_End", 0x01001134: "Hangul_Hanja", 0x01001135: "Hangul_Jamo", 0x01001136: "Hangul_Romaja", 0x01001138: "Hangul_Jeonja", 0x01001139: "Hangul_Banja", 0x0100113a: "Hangul_PreHanja", 0x0100113b: "Hangul_PostHanja", 0x0100113f: "Hangul_Special", 0x01001250: "Dead_Grave", 0x01001251: "Dead_Acute", 0x01001252: "Dead_Circumflex", 0x01001253: "Dead_Tilde", 0x01001254: "Dead_Macron", 0x01001255: "Dead_Breve", 0x01001256: "Dead_Abovedot", 0x01001257: "Dead_Diaeresis", 0x01001258: "Dead_Abovering", 0x01001259: "Dead_Doubleacute", 0x0100125a: "Dead_Caron", 0x0100125b: "Dead_Cedilla", 0x0100125c: "Dead_Ogonek", 0x0100125d: "Dead_Iota", 0x0100125e: "Dead_Voiced_Sound", 0x0100125f: "Dead_Semivoiced_Sound", 0x01001260: "Dead_Belowdot", 0x01001261: "Dead_Hook", 0x01001262: "Dead_Horn", 0x01001263: "Dead_Stroke", 0x01001264: "Dead_Abovecomma", 0x01001265: "Dead_Abovereversedcomma", 0x01001266: "Dead_Doublegrave", 0x01001267: "Dead_Belowring", 0x01001268: "Dead_Belowmacron", 0x01001269: "Dead_Belowcircumflex", 0x0100126a: "Dead_Belowtilde", 0x0100126b: "Dead_Belowbreve", 0x0100126c: "Dead_Belowdiaeresis", 0x0100126d: "Dead_Invertedbreve", 0x0100126e: "Dead_Belowcomma", 0x0100126f: "Dead_Currency", 0x01001280: "Dead_a", 0x01001281: "Dead_A", 0x01001282: "Dead_e", 0x01001283: "Dead_E", 0x01001284: "Dead_i", 0x01001285: "Dead_I", 0x01001286: "Dead_o", 0x01001287: "Dead_O", 0x01001288: "Dead_u", 0x01001289: "Dead_U", 0x0100128a: "Dead_Small_Schwa", 0x0100128b: "Dead_Capital_Schwa", 0x0100128c: "Dead_Greek", 0x01001290: "Dead_Lowline", 0x01001291: "Dead_Aboveverticalline", 0x01001292: "Dead_Belowverticalline", 0x01001293: "Dead_Longsolidusoverlay", 0x01000061: "Back", 0x01000062: "Forward", 0x01000063: "Stop", 0x01000064: "Refresh", 0x01000070: "VolumeDown", 0x01000071: "VolumeMute", 0x01000072: "VolumeUp", 0x01000073: "BassBoost", 0x01000074: "BassUp", 0x01000075: "BassDown", 0x01000076: "TrebleUp", 0x01000077: "TrebleDown", 0x01000080: "MediaPlay", 0x01000081: "MediaStop", 0x01000082: "MediaPrevious", 0x01000083: "MediaNext", 0x01000084: "MediaRecord", 0x1000085: "MediaPause", 0x1000086: "MediaTogglePlayPause", 0x01000090: "HomePage", 0x01000091: "Favorites", 0x01000092: "Search", 0x01000093: "Standby", 0x01000094: "OpenUrl", 0x010000a0: "LaunchMail", 0x010000a1: "LaunchMedia", 0x010000a2: "Launch0", 0x010000a3: "Launch1", 0x010000a4: "Launch2", 0x010000a5: "Launch3", 0x010000a6: "Launch4", 0x010000a7: "Launch5", 0x010000a8: "Launch6", 0x010000a9: "Launch7", 0x010000aa: "Launch8", 0x010000ab: "Launch9", 0x010000ac: "LaunchA", 0x010000ad: "LaunchB", 0x010000ae: "LaunchC", 0x010000af: "LaunchD", 0x010000b0: "LaunchE", 0x010000b1: "LaunchF", 0x0100010e: "LaunchG", 0x0100010f: "LaunchH", 0x010000b2: "MonBrightnessUp", 0x010000b3: "MonBrightnessDown", 0x010000b4: "KeyboardLightOnOff", 0x010000b5: "KeyboardBrightnessUp", 0x010000b6: "KeyboardBrightnessDown", 0x010000b7: "PowerOff", 0x010000b8: "WakeUp", 0x010000b9: "Eject", 0x010000ba: "ScreenSaver", 0x010000bb: "WWW", 0x010000bc: "Memo", 0x010000bd: "LightBulb", 0x010000be: "Shop", 0x010000bf: "History", 0x010000c0: "AddFavorite", 0x010000c1: "HotLinks", 0x010000c2: "BrightnessAdjust", 0x010000c3: "Finance", 0x010000c4: "Community", 0x010000c5: "AudioRewind", 0x010000c6: "BackForward", 0x010000c7: "ApplicationLeft", 0x010000c8: "ApplicationRight", 0x010000c9: "Book", 0x010000ca: "CD", 0x010000cb: "Calculator", 0x010000cc: "ToDoList", 0x010000cd: "ClearGrab", 0x010000ce: "Close", 0x010000cf: "Copy", 0x010000d0: "Cut", 0x010000d1: "Display", 0x010000d2: "DOS", 0x010000d3: "Documents", 0x010000d4: "Excel", 0x010000d5: "Explorer", 0x010000d6: "Game", 0x010000d7: "Go", 0x010000d8: "iTouch", 0x010000d9: "LogOff", 0x010000da: "Market", 0x010000db: "Meeting", 0x010000dc: "MenuKB", 0x010000dd: "MenuPB", 0x010000de: "MySites", 0x010000df: "News", 0x010000e0: "OfficeHome", 0x010000e1: "Option", 0x010000e2: "Paste", 0x010000e3: "Phone", 0x010000e4: "Calendar", 0x010000e5: "Reply", 0x010000e6: "Reload", 0x010000e7: "RotateWindows", 0x010000e8: "RotationPB", 0x010000e9: "RotationKB", 0x010000ea: "Save", 0x010000eb: "Send", 0x010000ec: "Spell", 0x010000ed: "SplitScreen", 0x010000ee: "Support", 0x010000ef: "TaskPane", 0x010000f0: "Terminal", 0x010000f1: "Tools", 0x010000f2: "Travel", 0x010000f3: "Video", 0x010000f4: "Word", 0x010000f5: "Xfer", 0x010000f6: "ZoomIn", 0x010000f7: "ZoomOut", 0x010000f8: "Away", 0x010000f9: "Messenger", 0x010000fa: "WebCam", 0x010000fb: "MailForward", 0x010000fc: "Pictures", 0x010000fd: "Music", 0x010000fe: "Battery", 0x010000ff: "Bluetooth", 0x01000100: "WLAN", 0x01000101: "UWB", 0x01000102: "AudioForward", 0x01000103: "AudioRepeat", 0x01000104: "AudioRandomPlay", 0x01000105: "Subtitle", 0x01000106: "AudioCycleTrack", 0x01000107: "Time", 0x01000108: "Hibernate", 0x01000109: "View", 0x0100010a: "TopMenu", 0x0100010b: "PowerDown", 0x0100010c: "Suspend", 0x0100010d: "ContrastAdjust", 0x01000110: "TouchpadToggle", 0x01000111: "TouchpadOn", 0x01000112: "TouchpadOff", 0x01000113: "MicMute", 0x01000114: "Red", 0x01000115: "Green", 0x01000116: "Yellow", 0x01000117: "Blue", 0x01000118: "ChannelUp", 0x01000119: "ChannelDown", 0x0100011a: "Guide", 0x0100011b: "Info", 0x0100011c: "Settings", 0x0100011d: "MicVolumeUp", 0x0100011e: "MicVolumeDown", 0x01000120: "New", 0x01000121: "Open", 0x01000122: "Find", 0x01000123: "Undo", 0x01000124: "Redo", 0x0100ffff: "MediaLast", 0x01ffffff: "unknown", 0x01100004: "Call", 0x01100020: "Camera", 0x01100021: "CameraFocus", 0x01100000: "Context1", 0x01100001: "Context2", 0x01100002: "Context3", 0x01100003: "Context4", 0x01100006: "Flip", 0x01100005: "Hangup", 0x01010002: "No", 0x01010000: "Select", 0x01010001: "Yes", 0x01100007: "ToggleCallHangup", 0x01100008: "VoiceDial", 0x01100009: "LastNumberRedial", 0x01020003: "Execute", 0x01020002: "Printer", 0x01020005: "Play", 0x01020004: "Sleep", 0x01020006: "Zoom", 0x0102000a: "Exit", 0x01020001: "Cancel"
        })
        property var modifierKeys: [Qt.Key_Alt, Qt.Key_Meta, Qt.Key_Control, Qt.Key_Shift, Qt.Key_NumLock, Qt.Key_Mode_switch]
    
        property bool lastWasNotModifier: false
        function parseKeyEvent(event, released) {
            if (!autoShortcut.checked)
                return
    
            if (!released && (event.key == Qt.Key_Backspace || event.key == Qt.Key_Delete) && event.modifiers == Qt.NoModifier) {
                text = ""
                event.accepted = true
                return
            }
    
            var isModifier = false
            modifierKeys.forEach(function(modifKey) {
                if (modifKey == event.key)
                    isModifier = true
            })
            if (released && lastWasNotModifier) {
                event.accepted = true
                return
            }
    
            lastWasNotModifier = !isModifier
    
            if (event.key == Qt.Key_unknown) {
                console.log("Unknown key from a macro probably")
                //text = ""
                event.accepted = true
                return
            }
    
            var result = ""
            // var result = lastWasNotModifier ? text + "," : ""
            if (!(event.modifiers & Qt.NoModifier)) {
                for(var modifier in modifiers) {
                    if (modifier & event.modifiers)
                        result += modifiers[modifier] + "+"
                }
            }
    
            if (!released && !isModifier) {
                result += keys[event.key]
            }
            if (text.endsWith('+')) {
                var t = text.split(',')
                text = t.slice(0, t.length - 1).join(',')
            }
            if (text) {
                if (text.endsWith(','))
                    text = text + result
                else
                    text = text + ',' + result
            }
            else {
                text = result
            }
            event.accepted = true
        }
        Keys.onPressed: parseKeyEvent(event, false)
        Keys.onReleased: parseKeyEvent(event, true)
    
        ToolButton {
            id: autoShortcut
            anchors {
                top: parent.top
                bottom: parent.bottom
                right: parent.right
                bottomMargin: 2
                topMargin: 2
                rightMargin: 2
            }
            text: qsTr("auto")
            checkable: true
            checked: true
            tooltip: qsTr("Wheter this line tries to create shortcut with you keypresses.\nIf disabled, you will be able to enter any key sequence as plain text")
        }
    }
    
    0 讨论(0)
提交回复
热议问题