qml 实现数值键盘

cpp 复制代码
import QtQuick 2.0
 import QtQuick.Layouts 1.12
import"../pad"
// PasswordKeyboard.qml
import QtQuick 2.12

ColumnLayout {
    id: keyboard
    spacing: 8

    // 键盘标题
    Text {
        text: "安全输入"
        font.pixelSize: 16
        color: "#666"
        Layout.alignment: Qt.AlignHCenter
        Layout.bottomMargin: 10
    }

    // 提示
    Text {
        text: "输入密码时,请确保周围环境安全"
        font.pixelSize: 14
        color: "#ff5252"
        Layout.alignment: Qt.AlignHCenter
    }

    // 键盘区域
    GridLayout {
        Layout.alignment: Qt.AlignHCenter
        columns: 4
        columnSpacing: 10
        rowSpacing: 10

        // 数字按键 1-9
        Repeater {
            model: 9

            Keybutton {
                text: index + 1
                width: 70
                height: 60
                onClicked: if (activeInputField) activeInputField.text += text
            }
        }

        // 特殊按键
        Keybutton {
            text: "0"
            width: 70
            height: 60
            onClicked: if (activeInputField) activeInputField.text += text
        }

        Keybutton {
            text: "⌫"
            width: 70
            height: 60
            bgColor: "#ff5252"
            onClicked: {
                if (activeInputField && activeInputField.text.length > 0) {
                    activeInputField.text = activeInputField.text.slice(0, -1);
                }
            }
        }

        Keybutton {
            text: "完成"
            width: 70
            height: 60
            bgColor: "#4CAF50"
            onClicked: keyboardClosed()
        }
    }

    // 信号
    signal keyboardClosed()

    // 属性
    property var activeInputField: null
}
cpp 复制代码
// KeyButton.qml
import QtQuick 2.12

Rectangle {
    id: button
    width: 60
    height: 50
    radius: 8

    // 公共属性
    property string text: ""
    property color bgColor: "white"
    property color textColor: "#333"

    // 信号
    signal clicked()

    color: mouseArea.pressed ? Qt.darker(bgColor, 1.1) : bgColor
    border.color: "#ddd"
    border.width: 1

    Text {
        text: button.text
        font.pixelSize: 20
        font.bold: true
        color: button.textColor
        anchors.centerIn: parent
    }

    MouseArea {
        id: mouseArea
        anchors.fill: parent
        onClicked: button.clicked()
    }
}

我们注意到代码中有几个问题需要修正:

  1. 特殊按键部分有两个按钮:一个是"0"按钮,另一个是退格按钮(但文本是".",这可能是设计错误,因为通常退格按钮用图标或"←"表示,而小数点按钮是".")。

  2. 当前代码中,小数点按钮实际上被用作退格(删除最后一个字符)功能,这显然是不正确的。根据按钮的文本,它应该是输入小数点,但点击事件却是删除。

  3. 另外,我们注意到有一个"0"按钮,宽度为140,而其他按钮宽度为70,这样布局可能会出现问题,因为GridLayout默认是左到右排列,并且我们设置了列间距。我们打算将键盘布局为3列,但是目前数字1-9有9个按钮(3x3),然后下面一行应该是一个宽按钮(0)占两列,然后一个小按钮(退格)占一列。但是代码中并没有明确设置列数(columns属性被注释了),而是通过flow和每个按钮的宽度来布局。 根据代码,我们想要3列布局,那么: 第一行:1,2,3 第二行:4,5,6 第三行:7,8,9 第四行:0(占两列宽度)和 一个退格按钮(占一列) 但是目前代码中,Repeater生成了9个按钮(1-9),然后接着是两个按钮:0和退格(当前显示为小数点,但功能是退格)。 问题在于,GridLayout在没有设置列数的情况下,会根据子项的宽度自动换行。我们期望第四行只有两个按钮:一个占两列(宽度140,等于两个70加上一个列间距10)的0按钮,和一个占一列(70)的退格按钮。但是,由于GridLayout的列间距为10,所以总宽度应该是:两列宽度(70*2)加上两个列间距(10*2)等于160,而0按钮宽度140小于160,所以实际上0按钮只会占据一列多,而不会自动跨两列。 因此,我们需要为0按钮设置Layout.columnSpan属性,让它横跨两列。同时,我们需要设置GridLayout的columns属性为3,这样布局才能按照3列来排列。

修改建议: 1. 取消注释columns: 3,设置为3列。

  1. 为0按钮设置Layout.columnSpan: 2,使其横跨两列。 3. 将小数点按钮的文本改为表示退格的符号(比如"←"),并调整其功能为删除最后一个字符。同时,添加一个小数点按钮,但是这里我们注意到,原代码中并没有小数点按钮,所以我们需要添加。 4. 但是原设计似乎只有10个键(1-9,0,退格),而小数点按钮缺失。根据常见数字键盘,通常有0、小数点、退格。因此,我们可能需要调整第四行为三个按钮:0、小数点、退格。但这样第四行就有三个按钮,而0按钮就不需要跨两列了。或者另一种常见布局是第四行有0(占一列)、小数点(占一列)、退格(占一列)。但是这样第四行就是三个按钮,与前三行对齐。 考虑到原设计是0按钮占140(两个70的宽度),而退格按钮占70,并且列间距10,那么0按钮的宽度140实际上等于两个按钮的宽度(70*2)加上一个列间距(10)。因此,如果我们设置3列,那么0按钮横跨两列,退格按钮占一列,这样第四行就只需要两个按钮(0和退格),而小数点没有位置了。 所以,我们需要重新设计第四行,有两种方案: 方案一:第四行三个按钮:0、.、退格,每个按钮宽度70。这样0按钮就不需要跨列了。 方案二:保持0按钮跨两列,然后退格按钮占一列,但这样就没有小数点按钮的位置了。 根据需求,我们需要小数点按钮。因此,我们采用方案一:第四行三个按钮:0、小数点、退格。 调整如下: 1. 将Repeater的9个按钮(1-9)生成后,再添加三个按钮:0、小数点、退格。 2. 设置GridLayout的columns为3,这样每行三个按钮。 3. 调整0按钮的宽度为70(与其他按钮一致),不再跨列。 但是,原代码中0按钮后面只有一个按钮(退格,但文本是小数点)。现在我们需要添加小数点按钮。 因此,我们将特殊按键部分拆分成三个按钮:0、小数点、退格。 同时,修正退格按钮的文本和功能: - 小数点按钮:文本为".",点击事件是追加小数点。 - 退格按钮:文本可以是"←"或"退格",点击事件是删除最后一个字符。
相关推荐
豆苗学前端9 分钟前
vue3+TypeScript 实现一个图片占位符生成器
前端·面试·github
neon120411 分钟前
Vue 3 父子组件通信核心机制详解:defineProps、defineEmits 与 defineExpose 完全指南
前端·javascript·vue.js·前端框架
Ciito16 分钟前
vue+moment将分钟调整为5的倍数(向下取整)
javascript·vue.js
Juchecar27 分钟前
Vue3 开发环境搭建及循序渐进学习指南
前端·javascript
Data_Adventure43 分钟前
@scqilin/phone-ui手机外观组件库
前端
一点一木1 小时前
Vue Vapor 事件机制深潜:从设计动机到源码解析
前端·vue.js·vapor
FSHOW1 小时前
记一次开源_大量SVG的高性能渲染
前端·react.js
小牛.7931 小时前
Web第二次作业
前端·javascript·css
二闹1 小时前
都2025了还要用Layui做下拉控件-我只能说你有水平
前端
Pikachu8031 小时前
揭秘 tyarn:一个为大型 TypeScript Monorepo 优化的 Yarn 性能猛兽
前端·javascript