Forums

OverviewFelgo 2 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.

Voted #1 for:

  • Easiest to learn
  • Most time saving
  • Best support

Develop Cross-Platform Apps and Games 50% Faster!

  • Voted the best supported, most time-saving and easiest to learn cross-platform development tool
  • Based on the Qt framework, with native performance and appearance on all platforms including iOS and Android
  • Offers a variety of plugins to monetize, analyze and engage users
FREE!
create apps
create games
cross platform
native performance
3rd party services
game network
multiplayer
level editor
easiest to learn
biggest time saving
best support