Learn what Felgo offers to help your business succeed. Start your free evaluation today! Felgo for Your Business

Forums

OverviewFelgo 3 Support (Qt 5) › MacOS accent characters

Tagged: ,

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #20952

    Phil

    Hello,

    I have an app with an AppTextEdit item. I want to type text with accented characters (é, à, etc). On MacOS you do this by holding down the key and then a pop up window shows, like this: http://osxdaily.com/2017/03/22/type-accents-mac-easy/. However, in my app when I hold down the key, it prints the character repeatedly. I also notice that if I turn off key repeats in the OS system preferences, this has no effect in my app. I understand this behaviour is useful for games where key repeats are needed, but is there any workaround for apps?

    Thanks,

    Phil

    #20969

    Günther
    Felgo Team

    Hi Phil,

    you can listen to Key-Events and prevent the forwarding in case the event is with auto-repeat:

    import Felgo 3.0
    import QtQuick 2.0
    
    App {
      NavigationStack  {
        Page  {
          title:  "Auto Repeat"
    
          AppTextEdit {
            id: field
            anchors.fill: parent
            placeholderText: "Type something ..."
    
            // do not forward key-events for autorepeat
            Keys.onPressed: {
              if (event.isAutoRepeat) {
                event.accepted = true
              }
            }
          }
        }
      }
    }
    
    

     

    #20985

    Phil

    Hi Günter,

    This prevents the key repeat, but now when I type the character (for example é), it shows e2é. Which is the exact key press sequence but not the output I want.

    Thanks,

    Phil

    #20986

    Günther
    Felgo Team

    A QML solution as above doesn’t really seem to fit then. You could also see if there’s a way to configure the auto-repeat event handling for the Qt application in general. I suggest to ask in the official Qt forums for input on that: https://forum.qt.io/

    Best,
    Günther

    #21268

    Phil

    I decided to implement this myself in a native solution. This gives me more control over what’s displayed and will work on any platform. Here’s my files:

    Main.qml

    import Felgo 3.0
    import QtQuick 2.5
    
    App {
        property var accents: {"a": ["à"], "e": ["é", "è", "ê"], "i": ["î"], "u": ["û"], "c": ["ç"]}
        property var accentList: ["a", "e", "i", "u", "c"]
        property var accentKeys: {"a": Qt.Key_A, "e": Qt.Key_E, "i": Qt.Key_I, "u": Qt.Key_U, "c": Qt.Key_C}
        property string currentAccent: ""
        property bool showAccents: false
    
        // insert the character at the given cursor index
        function insertAtCursor(cursorIdx, text, chr) {
            var keepIdx = cursorIdx-1
            return text.slice(0, keepIdx) + chr + text.slice(cursorIdx)
        }
    
        function forEachAccent(fn) {
            for(var i=0; i<accentList.length; i++) {
                fn(accentList[i], accentKeys[accentList[i]], accents[accentList[i]])
            }
        }
    
        ShortcutHandler {}
    
        AppTextEdit {
            id: textEdit
            placeholderText: "type here"
            focus: true
            anchors.verticalCenter: parent.verticalCenter
            x: parent.width / 3
    
            Keys.onPressed: {
                // ignore repeats of accent keys: 'a', 'e', etc
                if(event.isAutoRepeat) {
                    var accept = false
                    forEachAccent(function(chr, key, list) {
                        if(event.key == key) {
                            accept = true
                        }
                    })
                    event.accepted = accept
                    return
                }
    
                // if the accent pop up is showing, then intercept the number keys and replace the text with the accent
                if(showAccents) {
                    if(event.key >= Qt.Key_1 && event.key <= Qt.Key_1 + accents[currentAccent].length) {
                        console.log(accents[currentAccent][event.key-Qt.Key_1])
                        var cursorIdx = textEdit.cursorPosition
                        textEdit.text = insertAtCursor(cursorIdx, textEdit.text, accents[currentAccent][event.key-Qt.Key_1])
                        textEdit.cursorPosition = cursorIdx
    
                        showAccents = false
                        currentAccent = ""
                        event.accepted = true
                        return
                    }
                }
    
                // check if the key press was an accent character and if so,
                // start a timer to count how long it's held down for
                currentAccent = ""
                showAccents = false
                forEachAccent(function(chr, key, list) {
                    if(key == event.key) {
                        currentAccent = chr
                        autoRepeatThreshold.start()
                    }
                })
            }
    
            Keys.onReleased: {
                autoRepeatThreshold.stop()
            }
    
            AccentsPopup {
                id: accentsBox
                x: -width/2 + textEdit.cursorRectangle.x
                anchors.bottom: parent.top
            }
        }
    
        Timer {
            id: autoRepeatThreshold
            running: false
            repeat: false
            interval: 300
            onTriggered: {
                showAccents = true
            }
        }
    }

    ShortcutHandler.qml

    import Felgo 3.0
    import QtQuick 2.5
    
    Item {
        id: shortcutHandler
    
        Shortcut {
            sequence: 'Escape'
            context: Qt.ApplicationShortcut
            onActivated: {
                showAccents = false
                currentAccent = ""
            }
        }
    }

    AccentsPopup.qml

    import Felgo 3.0
    import QtQuick 2.5
    
    Rectangle {
        visible: showAccents
        width: accentText.width + dp(20)
        height: dp(40)
        radius: dp(2)
        Grid {
            id: accentText
            columns: currentAccent === "" ? 0 : accents[currentAccent].length
            anchors.horizontalCenter: parent.horizontalCenter
            columnSpacing: dp(10)
            Repeater {
                model: currentAccent === "" ? [] : accents[currentAccent]
                AppText {
                    text: currentAccent === "" ? [] : accents[currentAccent][index]
                    font.pointSize: dp(15)
                }
            }
            Repeater {
                model: currentAccent === "" ? [] : accents[currentAccent]
                AppText {
                    text: index + 1
                    color: "#777777"
                    font.pointSize: dp(15)
                }
            }
        }
    
        PolygonItem {
            id: triangle
            anchors.top: parent.bottom
            anchors.horizontalCenter: parent.horizontalCenter
            color: parent.color
            fill: true
            vertices: [
                Qt.point(0, 0),
                Qt.point(20, 0),
                Qt.point(10, 10)
            ]
        }
    }

    My only issue now is when trying to override the Escape shortcut to cancel the input, I get the message  QQuickAction::event: Ambiguous shortcut overload: ?. Is this a Qt issue or a Felgo issue?

     

    Thanks,

    Phil

    #21271

    Günther
    Felgo Team
    #21278

    Phil

    Yes this works. Thanks =]

Viewing 7 posts - 1 through 7 (of 7 total)

RSS feed for this thread

You must be logged in to reply to this topic.

Qt_Technology_Partner_RGB_475 Qt_Service_Partner_RGB_475_padded