Qt Quick Controls 2个旋转框上的屏幕数字键盘

时间:2017-01-26 02:38:00

标签: qt qtquickcontrols2

在触摸屏应用程序中,是否可以从QtQuickControls 2.0编辑qml SpinBox的整数值,这样屏幕上会出现一个数字键盘,并且可以输入确切的值?

或者你对如何在自定义的旋转框中嵌入this predefined number pad有任何想法,当用户点击整数时会弹出这个?#/ p>

2 个答案:

答案 0 :(得分:0)

小键盘可以设置为不可见并置于所有内容之上,然后您可以使用一个功能来启用其可见性并设置它的目标。键入数字后,将目标值设置为numpad值,然后再次隐藏它。通过这种方式,您可以定位不同的旋转框。

在请求键盘的实际方法中,您可以放置​​一个MouseArea来填充旋转框。或者您可以使鼠标区域更窄,以便旋转框的加/减按钮仍然可以点击。

另请注意,您链接的小键盘实际上并不起作用。

答案 1 :(得分:0)

感谢您的建议。我根据你的想法和示例部分的数字键盘提出了第一个快速解决方案。我在这里发布,以防万一作为起点帮助别人。我是QML的初学者,很高兴得到任何改进或更正。

See attached screenshot of the numeric virtual touchpad appearing when clicking on the spinbox number

SpinBox {
    id: boxCommPos
    x: 50
    y: 50
    z: 0
    width: 200
    height: 50
    to: 360
    editable: false

    contentItem: TextInput {
        z: 1
        text: parent.textFromValue(parent.value, parent.locale)

        font: parent.font
        //color: "#21be2b"
        //selectionColor: "#21be2b"
        //selectedTextColor: "#ffffff"

        horizontalAlignment: Qt.AlignHCenter
        verticalAlignment: Qt.AlignVCenter

        readOnly: !parent.editable
        validator: parent.validator
        inputMethodHints: Qt.ImhFormattedNumbersOnly
    }

    Label {
        id: commUnits
        x: 125
        y: 0
        z: 3
        text: qsTr("º")
        font.pointSize: 16
        anchors.right: parent.right
        anchors.rightMargin: 45
    }

    MouseArea {
        id: padCommPos
        x: 40
        y: 0
        z: 2
        width: parent.width-x-x
        height: 50
        onClicked: touchpad.visible=true
    }
}

NumberTouchpad {
    id: touchpad
    x: 470
    y: -20
    z: 1
    scale: 0.90
    visible: false

    Rectangle {
        id: backrect
        x: -parent.x/parent.scale
        z: -1
        width: parent.parent.width/parent.scale
        height: parent.parent.height/parent.scale
        color: "#eceeea"
        opacity: 0.5
        MouseArea {
            anchors.fill: parent
        }
    }
}

文件NumberPad.qml

import QtQuick 2.0

Grid {
    columns: 3
    columnSpacing: 32
    rowSpacing: 16

    signal buttonPressed

    Button { text: "7" }
    Button { text: "8" }
    Button { text: "9" }
    Button { text: "4" }
    Button { text: "5" }
    Button { text: "6" }
    Button { text: "1" }
    Button { text: "2" }
    Button { text: "3" }
    Button { text: "0" }
    Button { text: "."; dimmable: true }
    //Button { text: " " }
    Button { text: "±"; color: "#6da43d"; operator: true; dimmable: true }
    //Button { text: "−"; color: "#6da43d"; operator: true; dimmable: true }
    //Button { text: "+"; color: "#6da43d"; operator: true; dimmable: true }
    //Button { text: "√"; color: "#6da43d"; operator: true; dimmable: true }
    //Button { text: "÷"; color: "#6da43d"; operator: true; dimmable: true }
    //Button { text: "×"; color: "#6da43d"; operator: true; dimmable: true }
    Button { text: "C"; color: "#6da43d"; operator: true }
    Button { text: "✔"; color: "#6da43d"; operator: true; dimmable: true }
    Button { text: "X"; color: "#6da43d"; operator: true }

}

Display.qml

// Copyright (C) 2015 The Qt Company Ltd.
import QtQuick 2.0
import QtQuick.Window 2.0    
Item {
    id: display
    property real fontSize: Math.floor(Screen.pixelDensity * 10.0)
    property string fontColor: "#000000"
    property bool enteringDigits: false
    property int maxDigits: (width / fontSize) + 1
    property string displayedOperand
    property string errorString: qsTr("ERROR")
    property bool isError: displayedOperand === errorString

    function displayOperator(operator)
    {
        listView.model.append({ "operator": operator, "operand": "" })
        enteringDigits = true
        listView.positionViewAtEnd()
        //console.log("display",operator);
    }

    function newLine(operator, operand)
    {
        displayedOperand = displayNumber(operand)
        listView.model.append({ "operator": operator, "operand": displayedOperand })
        enteringDigits = false
        listView.positionViewAtEnd()
        //console.log("newLine",operator);
    }

    function appendDigit(digit)
    {
        if (!enteringDigits)
            listView.model.append({ "operator": "", "operand": "" })
        var i = listView.model.count - 1;
        listView.model.get(i).operand = listView.model.get(i).operand + digit;
        enteringDigits = true
        listView.positionViewAtEnd()
        //console.log("num is ", digit);
    }

    function setDigit(digit)
    {
        var i = listView.model.count - 1;
        listView.model.get(i).operand = digit;
        listView.positionViewAtEnd()
        //console.log("setDigit",digit);
    }

    function clear()
    {
        displayedOperand = ""
        if (enteringDigits) {
            var i = listView.model.count - 1
            if (i >= 0)
                listView.model.remove(i)
            enteringDigits = false
        }
        //console.log("clearing");
    }

    // Returns a string representation of a number that fits in
    // display.maxDigits characters, trying to keep as much precision
    // as possible. If the number cannot be displayed, returns an
    // error string.
    function displayNumber(num) {
        if (typeof(num) != "number")
            return errorString;

        var intNum = parseInt(num);
        var intLen = intNum.toString().length;

        // Do not count the minus sign as a digit
        var maxLen = num < 0 ? maxDigits + 1 : maxDigits;

        if (num.toString().length <= maxLen) {
            if (isFinite(num))
                return num.toString();
            return errorString;
        }

        // Integer part of the number is too long - try
        // an exponential notation
        if (intNum == num || intLen > maxLen - 3) {
            var expVal = num.toExponential(maxDigits - 6).toString();
            if (expVal.length <= maxLen)
                return expVal;
        }

        // Try a float presentation with fixed number of digits
        var floatStr = parseFloat(num).toFixed(maxDigits - intLen - 1).toString();
        if (floatStr.length <= maxLen)
            return floatStr;

        return errorString;
    }

    Item {
        id: theItem
        width: parent.width
        height: parent.height

        Rectangle {
            id: rect
            x: 0
            color: "#eceeea"
            height: parent.height
            width: display.width
        }
        /*Image {
            anchors.right: rect.left
            source: "images/paper-edge-left.png"
            height: parent.height
            fillMode: Image.TileVertically
        }
        Image {
            anchors.left: rect.right
            source: "images/paper-edge-right.png"
            height: parent.height
            fillMode: Image.TileVertically
        }

        Image {
            id: grip
            source: "images/paper-grip.png"
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 20
        }*/

        ListView {
            id: listView
            width: display.width
            height: display.height
            delegate: Item {
                height: display.fontSize * 1.1
                width: parent.width
                Text {
                    id: operator
                    font.pixelSize: display.fontSize
                    color: "#6da43d"
                    text: model.operator
                }
                Text {
                    id: operand
                    y:5
                    font.pixelSize: display.fontSize
                    color: display.fontColor
                    anchors.right: parent.right
                    anchors.rightMargin: 22
                    text: model.operand
                }
            }
            model: ListModel { }
        }

    }

}

calculator.qs     //版权所有(C)2015 The Qt Company Ltd.

var curVal = 0
var memory = 0
var lastOp = ""
var previousOperator = ""
var digits = ""

function disabled(op) {
    if (op == "✔")
        display.fontColor="#000000"

    if (op=="X")
        return false
    else if (op == "✔" && (digits.toString().search(/\./) != -1  || digits.toString().search(/-/)!= -1 || parseInt(digits)>359)) {
        display.fontColor="#ff0000"
        return true
    }
    else if (digits == "" && !((op >= "0" && op <= "9") || op == "."))
        return true
    else if (op == '=' && previousOperator.length != 1)
        return true
    else if (op == "." && digits.toString().search(/\./) != -1) {
        return true
    } else if (op == "√" &&  digits.toString().search(/-/) != -1) {
        return true
    } else {
        return false
    }
}

function digitPressed(op)
{
    if (disabled(op))
        return
    if (digits.toString().length >= display.maxDigits)
        return
    if (lastOp.toString().length == 1 && ((lastOp >= "0" && lastOp <= "9") || lastOp == ".") ) {
        digits = digits + op.toString()
        display.appendDigit(op.toString())
    } else {
        digits = op
        display.appendDigit(op.toString())
    }
    lastOp = op
}

function operatorPressed(op)
{
    if (disabled(op))
        return
    lastOp = op

    if (op == "±") {
            digits = Number(digits.valueOf() * -1)
            display.setDigit(display.displayNumber(digits))
            return
        }

    if (previousOperator == "+") {
        digits = Number(digits.valueOf()) + Number(curVal.valueOf())
    } else if (previousOperator == "−") {
        digits = Number(curVal.valueOf()) - Number(digits.valueOf())
    } else if (previousOperator == "×") {
        digits = Number(curVal) * Number(digits.valueOf())
    } else if (previousOperator == "÷") {
        digits = Number(curVal) / Number(digits.valueOf())
    }

    if (op == "+" || op == "−" || op == "×" || op == "÷") {
        previousOperator = op
        curVal = digits.valueOf()
        digits = ""
        display.displayOperator(previousOperator)
        return
    }

    if (op == "=") {
        display.newLine("=", digits.valueOf())
    }

    curVal = 0
    previousOperator = ""

    if (op == "1/x") {
        digits = (1 / digits.valueOf()).toString()
    } else if (op == "x^2") {
        digits = (digits.valueOf() * digits.valueOf()).toString()
    } else if (op == "Abs") {
        digits = (Math.abs(digits.valueOf())).toString()
    } else if (op == "Int") {
        digits = (Math.floor(digits.valueOf())).toString()
    } else if (op == "√") {
        digits = Number(Math.sqrt(digits.valueOf()))
        display.newLine("√", digits.valueOf())
    } else if (op == "mc") {
        memory = 0;
    } else if (op == "m+") {
        memory += digits.valueOf()
    } else if (op == "mr") {
        digits = memory.toString()
    } else if (op == "m-") {
        memory = digits.valueOf()
    } else if (op == "backspace") {
        digits = digits.toString().slice(0, -1)
        display.clear()
        display.appendDigit(digits)
    } else if (op == "✔") {
        window.visible=false
        boxCommPos.value=parseInt(digits)
        display.clear()
        curVal = 0
        memory = 0
        lastOp = ""
        digits = ""

    } else if (op == "X") {
        window.visible=false
        display.clear()
        curVal = 0
        memory = 0
        lastOp = ""
        digits = ""
    }

    // Reset the state on 'C' operator or after
    // an error occurred
    if (op == "C" || display.isError) {
        display.clear()
        curVal = 0
        memory = 0
        lastOp = ""
        digits = ""
    }
}

Button.qml     //版权所有(C)2015 The Qt Company Ltd.

import QtQuick 2.0

Item {
    id: button
    property alias text: textItem.text
    property color color: "#eceeea"

    property bool operator: false
    property bool dimmable: false
    property bool dimmed: false

    width: 30
    height: 50

    Text {
        id: textItem
        font.pixelSize: 48
        wrapMode: Text.WordWrap
        lineHeight: 0.75
        color: (dimmable && dimmed) ? Qt.darker(button.color) : button.color
        Behavior on color { ColorAnimation { duration: 120; easing.type: Easing.OutElastic} }
        states: [
            State {
                name: "pressed"
                when: mouse.pressed && !dimmed
                PropertyChanges {
                    target: textItem
                    color: Qt.lighter(button.color)
                }
            }
        ]
    }

    MouseArea {
        id: mouse
        anchors.fill: parent
        anchors.margins: -5
        onClicked: {
            if (operator)
                window.operatorPressed(parent.text)
            else
                window.digitPressed(parent.text)
        }
    }

    function updateDimmed() {
        dimmed = window.isButtonDisabled(button.text)
    }

    Component.onCompleted: {
        numPad.buttonPressed.connect(updateDimmed)
        updateDimmed()
    }
}