QML构件——数字键盘

        在移动端,特别是触屏机器上,需要使用到数字键盘来进行输入,一种方法是可以引入qt自带的键盘模块,但是效果并不是特别理想(主要是界面的控制)。

        自己使用qml简单写了一个使用起来也还比较方便。如下图是主界面的展示:

——————————————————————————————————华丽的分割线        

下面就是构件的详细设计步骤。

step1:工程结构

step2:main.qml主窗口代码分析

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12


Window {
    id: root
    visible: true
    width: 640
    height: 480
    title: qsTr("数字键盘demo")
    color: "white"

    Rectangle{
        anchors.left: parent.left
        anchors.top: parent.top
        width: 200
        height: 50
        border.color: "red"

        TextInput {
            font.pointSize: 21
            width: parent.width
            height: parent.height
            color: "black"
            text: "111111"

            //数字键盘模式
            inputMethodHints: Qt.ImhDigitsOnly
            //在focuse时触发
            onActiveFocusChanged: {
                if(activeFocus){
                    gVirtualKeyboard.show(this)
                }
            }

        }
    }

    //虚拟键盘
    NumberVirtualKeyboard{
        id: gVirtualKeyboard
        x:150
        y:150
    }

}

主要是生成了一个主窗体,然后定义了一个输入框和虚拟键盘:NumberVirtualKeyboard

在TextInput中需要处理一下,设置点击时触发,gVirtualKeyboard就是我们定义的虚拟键盘

step3:NumberVirtualKeyboard.qml虚拟键盘的代码分析

import QtQuick 2.0

Rectangle{
    id: root
    width: 350
    height: 300
    radius: 5
    border.color: "white"
    border.width: 2
    color: Qt.rgba(0,0,0,0.3)

    visible: false
    property var inputControl: null
    property var lastX: x
    property var lastY: y


    Item{
        id: title
        anchors.left: parent.left
        anchors.top: parent.top
        width: parent.width
        height: 40

        //处理拖拽
        MouseArea{
            id: dragMA
            anchors.fill: parent

            onPressed: {
                //鼠标按下时,记录鼠标初始位置
                root.lastX = mouseX
                root.lastY = mouseY
            }

            onPositionChanged: {
                if (pressed) {
                    //鼠标按住的前提下,坐标改变时,计算偏移量,应用到目标item的坐标上即可
                    root.x += mouseX - root.lastX
                    root.y += mouseY - root.lastY
                }
            }
        }

        //关闭按钮
        Text {
            id: close
            anchors.right: parent.right
            anchors.margins: 5
            text: qsTr("X")
            color: "white"
            font{
                family: "微软雅黑"
                pixelSize: 35
                bold: true
            }
            MouseArea{
                anchors.fill: parent
                onClicked: {
                    root.visible = false
                    inputControl.focus = false
                }
            }
        }
    }

    Rectangle{
        width:parent.width-4
        height: root.height - title.height -4
        anchors.bottomMargin: 2
        anchors.bottom: parent.bottom
        anchors.horizontalCenter: parent.horizontalCenter

        color: Qt.rgba(0,0,0,0.6)
        Flow {
            id: flow

            width: parent.width-10
            height: parent.height-10
            anchors.centerIn: parent
            spacing: 10

            Repeater {
                id: btnRepeater
                anchors.fill: parent
                model: ["7","8","9","Del",
                        "4","5","6","—",
                        "1","2","3",".",
                        "<","0",">","确认"]
                Rectangle{
                    width: 76
                    height: 55
                    color: "#14b17e"
                    radius: 6

                    Text {
                        id: nameUi
                        text: modelData
                        font.pixelSize: 24
                        anchors.centerIn: parent
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                        color: "white"
                        font.bold: true
                        font.family: "微软雅黑"
                        //自适应缩小
                        wrapMode: Text.Wrap
                        fontSizeMode:Text.HorizontalFit
                        minimumPointSize: 5
                    }

                    MouseArea{
                        anchors.fill: parent
                        onClicked: doInput(modelData)
                    }

                }
            }
        }
    }


    //对外的接口,传入的是inputText控件
    function show(tmpInputControl){
        inputControl = tmpInputControl
        gVirtualKeyboard.visible = true
    }

    ///内部接口
    function doInput(strData){
        if(!inputControl)
            return
        //console.log(strData)
        switch(strData){
        case "Del":
            removeCharAtCursor()
            break;
        case "—":
            if(inputControl.cursorPosition===0&&inputControl.text.slice(0, 1)!=="-")
                insertAtCursor("-")
            break;
        case "<":
            moveCursorLeft()
            break;
        case ">":
            moveCursorRight()
            break;
        case "确认":
            doConfirm()
            break;
        default:
            if(inputControl.cursorPosition===0 && inputControl.text.slice(0, 1)==="-")
                return
            if(inputControl.text.indexOf(".") !== -1 && strData===".")
                return
            insertAtCursor(strData)
        }
    }

    // 在光标处添加字符
    function insertAtCursor(strData) {
        var startPos = inputControl.selectionStart
        var endPos = inputControl.selectionEnd
        var beforeText = inputControl.text.substring(0, startPos)
        var afterText = inputControl.text.substring(endPos, inputControl.text.length)
        inputControl.text = beforeText + strData + afterText
        inputControl.cursorPosition = startPos + strData.length;
    }

    //光标左移一个位置
    function moveCursorLeft() {
        if (inputControl.cursorPosition > 0) {
            inputControl.cursorPosition -= 1;
        }
    }

    // 光标右移一个位置
    function moveCursorRight() {
        if (inputControl.cursorPosition < inputControl.text.length) {
            inputControl.cursorPosition += 1;
        }
    }

    //执行确认
    function doConfirm() {
        inputControl.accepted()
    }

    // 删除光标处的字符
    function removeCharAtCursor() {
        if (inputControl.text.length > 0 && inputControl.cursorPosition >0) {
            var start = inputControl.cursorPosition
            var end = start
            inputControl.text = inputControl.text.slice(0, start-1) + inputControl.text.slice(end)
            inputControl.cursorPosition = start - 1
        }
    }

    //del all str
    function delAllChar() {
        inputControl.text = ""
    }
}

如图对外接口就是内部的show接口,传入的参数是inputText控件

对内接口都在下方,都留了注释。

核心代码都已展示,后续再上传完整工程代码,需要的朋友可自行下载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值