QML만 가지고 7 Segment LED를 흉내 내보고 싶다. 물론 TTF를 이용하면 편하겠지
(사실 그게 더 현명한 방법일 수도 있겠다는 생각이 작업을 하고 나서야 들었다.)
Main.qml
Window {
visible: true width: 640 height: 480 title: qsTr("LED Number Test")
TextField { id: txt x: 0 y: 0 placeholderText: "Enter a number" width: 200 onTextChanged: display.value = text } Rectangle{ x: 0 y: 100 width: parent.width*0.5 height: parent.width*0.09 color: "black" SevenSegmentDisplay{ id: display x: 10 y: 10 value: "value" charWidth: parent.width*0.05 } }}
SevenSegmentElement.qmlItem {
id: root
property int elementWidth: 10
property color fillColor: "#FFCC00"
property bool horizontal: false
width: elementWidth*(horizontal??true?5:1)
height: elementWidth*(horizontal??true?1:5)
Rectangle{
color: "transparent"
width: elementWidth*(horizontal??true?5:1)
height: elementWidth*(horizontal??true?1:5)
Canvas{
anchors.fill:parent
onPaint:{
var context = getContext("2d");
context.beginPath();
context.moveTo(parent.x + (horizontal??true?root.elementWidth * 0.5:0)
,parent.y + root.elementWidth*(horizontal??true?0.5:1)); // 1
context.lineTo(parent.x + root.elementWidth * (horizontal??true?1:0.5)
, parent.y + root.elementWidth * (horizontal??true?0:0.5)); // 2
context.lineTo(parent.x + parent.width - (horizontal??true?root.elementWidth:0)
, parent.y + root.elementWidth * (horizontal??true?0:1)); // 3
context.lineTo(parent.x + parent.width - root.elementWidth * (horizontal??true?0.5:0)
, parent.y + root.elementWidth * (horizontal??true?0.5:1)); // 4
context.lineTo(parent.x + parent.width - root.elementWidth *(horizontal??true?0.5:0)
, parent.y + parent.height - root.elementWidth*(horizontal??true?0.5:1)); // 5
context.lineTo(parent.x + parent.width - root.elementWidth*(horizontal??true?1:0.5)
, parent.y + parent.height - root.elementWidth*(horizontal??true?0:0.5) ); // 6
context.lineTo(parent.x + root.elementWidth*(horizontal??true?1:0.5)
, parent.y + parent.height - root.elementWidth*(horizontal??true?0:0.5)); // 7
context.lineTo(parent.x + root.elementWidth * (horizontal??true?0.5:0)
, parent.y + parent.height - root.elementWidth * (horizontal??true?0.5:1)); // 8
context.closePath();
// the fill color
context.fillStyle = fillColor;//"#FFCC00";
context.fill();
}
}
}
}
SevenSegment.qmlItem {
property int digit : 0
property bool showDot: false
property bool showComma: false
property int charWidth: 80
property color charColor: "black"
width: charWidth
property var segmentMap: [
[true,true,true,true,true,true,false], // 0
[false,true,true,false,false,false,false], // 1
[true,true,false,true,true,false,true], // 2
[true,true,true,true,false,false,true], // 3
[false,true,true,false,false,true,true], // 4
[true,false,true,true,false,true,true], // 5
[true,false,true,true,true,true,true], // 6
[true,true,true,false,false,false,false], // 7
[true,true,true,true,true,true,true], // 8
[true,true,true,true,false,true,true], // 9
[false,false,false,false,false,false,false], // (space)
[false,false,false,false,false,false,true], // (-)
[true,true,true,false,true,true,true], // A
[false,false,true,true,true,true,true], // b
[false,false,false,true,true,false,true], // c
[false,true,true,true,true,false,true], // d
[true,false,false,true,true,true,true], // E
[true,false,false,false,true,true,true], // F
[true,false,true,true,true,true,false], // G
[false,false,true,false,true,true,true], // h
[false,false,true,false,false,false,false], // i
[false,true,true,true,true,false,false], // J
[true,false,true,false,true,true,true], // K
[false,false,false,true,true,true,false], // L
[true,true,true,false,true,true,false], // M
[false,false,true,false,true,false,true], // n
[false,false,true,true,true,false,true], // o
[true,true,false,false,true,true,true], // p
[true,true,true,false,false,true,true], // q
[false,false,false,false,true,false,true], // r
[false,false,true,true,false,true,true], // s
[false,false,false,true,true,true,true], // t
[false,false,true,true,true,false,false], // u
[false,true,true,true,true,true,false], // V
[false,true,true,true,true,true,true], // W
[false,true,true,false,true,true,true], // X
[false,true,true,true,false,true,true], // y
[true,true,false,true,true,false,false] // Z
]
Rectangle{
// border.color:"blue"
// border.width: 1
color: "transparent"
width: charWidth *1.2
height: charWidth * 2.3
SevenSegmentElement {
id:seg_A
x:parent.x
y:parent.y
elementWidth: charWidth/4
horizontal: true
fillColor: charColor
visible: segmentMap[digit][0]
}
SevenSegmentElement {
id:seg_B
x:parent.x+charWidth
y:parent.y
elementWidth: charWidth/4
horizontal: false
fillColor: charColor
visible: segmentMap[digit][1]
}
SevenSegmentElement {
id:seg_C
x:parent.x+charWidth
y:parent.y+charWidth
elementWidth: charWidth/4
horizontal: false
fillColor: charColor
visible: segmentMap[digit][2]
}
SevenSegmentElement {
id:seg_D
x:parent.x
y:parent.y+charWidth*2
elementWidth: charWidth/4
horizontal: true
fillColor: charColor
visible: segmentMap[digit][3]
}
SevenSegmentElement {
id:seg_E
x:parent.x
y:parent.y+charWidth
elementWidth: charWidth/4
horizontal: false
fillColor: charColor
visible: segmentMap[digit][4]
}
SevenSegmentElement {
id:seg_F
x:parent.x
y:parent.y
elementWidth: charWidth/4
horizontal: false
fillColor: charColor
visible: segmentMap[digit][5]
}
SevenSegmentElement {
id:seg_G
x:parent.x
y:parent.y+charWidth
elementWidth: charWidth/4
horizontal: true
fillColor: charColor
visible: segmentMap[digit][6]
}
Rectangle {
x: parent.x + parent.width/2
y: parent.y + parent.height - charWidth/5
width: charWidth/5
height: charWidth/5
color: charColor
radius: width*0.2
visible: showDot||showComma
}
Rectangle{
x: parent.x + parent.width/2 + charWidth/5 - charWidth/7
y: parent.y + parent.height - charWidth/12
width: charWidth/7
height: charWidth/7
color: charColor
radius: width*0.2
visible: showComma
}
}
}
SevenSegmentDisplay.qml
Item { id: root property string value : "0" property int spacing: 10 property color charColor: "lime"
property int charWidth: 20 Rectangle{ // border.color: "red" // border.width:2 // width: charWidth*(parsedDigits.length*1.2) // height: charWidth*2.1 Row { id: digitRow spacing: root.spacing Repeater { model: parsedDigits.length SevenSegment { x: index*charWidth*1.5// +/root.spacing digit: parsedDigits[index].digit showDot: parsedDigits[index].dot showComma: parsedDigits[index].comma charColor: root.charColor charWidth: root.charWidth //height: root.digitHeight width: root.charWidth } } } } // 내부적으로 처리된 자릿수 정보 (digit + dot 여부) property var parsedDigits: []
function parseText(input) { let result = []; if(parseInt(input)<0){ result.push({ digit: 11, dot: false, comma: false}) // - input = input.substring(1,input.length) }
for (let i = 0; i < input.length; ++i) { let c = input[i];
if (c >= "0" && c <= "9") { // 기본 digit let digitObj = { digit: parseInt(c), dot: false , comma: false}; result.push(digitObj); } else if (c === ".") { // 소수점 result.push({ digit: 10, dot: true, comma: false}); } else if (c === ",") { // 콤마: 빈 digit + dot 사용 result.push({ digit: 10, dot: true , comma: true}); } else if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'){ var charIdx = input.toUpperCase().charCodeAt(i) - 53 //(A(65)+12) let digitVal = {digit:charIdx, dot:false, comma: false};// console.log(c+":"+c.toUpperCase()+":"+charIdx+":"+input.toUpperCase().charCodeAt(i)); result.push(digitVal); } } return result; }
onValueChanged: { parsedDigits = parseText(value); }
Component.onCompleted: { parsedDigits = parseText(value); }}
댓글 없음:
댓글 쓰기