在移动端,特别是触屏机器上,需要使用到数字键盘来进行输入,一种方法是可以引入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控件
对内接口都在下方,都留了注释。
核心代码都已展示,后续再上传完整工程代码,需要的朋友可自行下载。