qmlで7セグメント表示
文書の過去の版を表示しています。
QMLで7セグメント風表示
- SevenSegment.qml
import QtQuick Canvas { id: canvas width: 100; height: 160 // 入力プロパティ property int value: 0 property bool showDot: false property real reading: 0 // 現在のセンサー数値 property real threshold1: 0 // アンバーになる値 property real threshold2: 0 // 赤になる値 // デザイン設定 property real skewAngle: 8 property real gap: 4 property real thickness: 16 // 状態に基づいた色の自動判定 readonly property color activeColor: { if (reading >= threshold2) return "#CC0000"; // やや暗めの赤 if (reading >= threshold1) return "#FFBF00"; // アンバー return "#006622"; // 通常時の暗めの緑 } readonly property color inactiveColor: "#051505" // 消灯時(背景に馴染ませる) // 再描画トリガー onActiveColorChanged: requestPaint() onValueChanged: requestPaint() onShowDotChanged: requestPaint() antialiasing: true onPaint: { var ctx = getContext("2d"); ctx.reset(); ctx.clearRect(0, 0, width, height); var angleRad = skewAngle * Math.PI / 180; ctx.transform(1, 0, -Math.tan(angleRad), 1, height * Math.tan(angleRad), 0); var p = [ 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x27, 0x7F, 0x6F ][value % 10] || 0; function drawShape(points, on) { ctx.beginPath(); ctx.moveTo(points[0].x, points[0].y); for (var i = 1; i < points.length; i++) ctx.lineTo(points[i].x, points[i].y); ctx.closePath(); ctx.fillStyle = on ? activeColor : inactiveColor; // 閾値を超えた時だけ少し光らせる演出 ctx.shadowBlur = (on && reading >= threshold1) ? 10 : 0; ctx.shadowColor = activeColor; ctx.fill(); } var w = width * 0.75; var h = height; var t = thickness; var g = gap; // セグメント座標計算 (六角形) drawShape([{x:t+g, y:0}, {x:w-t-g, y:0}, {x:w-t*1.5-g, y:t}, {x:t*1.5+g, y:t}], p & 0x01); // A drawShape([{x:w-t, y:t+g}, {x:w, y:t*1.5+g}, {x:w, y:h/2-t/2-g}, {x:w-t, y:h/2-g}], p & 0x02); // B drawShape([{x:w-t, y:h/2+g}, {x:w, y:h/2+t/2+g}, {x:w, y:h-t*1.5-g}, {x:w-t, y:h-t-g}], p & 0x04); // C drawShape([{x:t*1.5+g, y:h-t}, {x:w-t*1.5-g, y:h-t}, {x:w-t-g, y:h}, {x:t+g, y:h}], p & 0x08); // D drawShape([{x:0, y:h/2+t/2+g}, {x:t, y:h/2+g}, {x:t, y:h-t-g}, {x:0, y:h-t*1.5-g}], p & 0x10); // E drawShape([{x:0, y:t*1.5+g}, {x:t, y:t+g}, {x:t, y:h/2-g}, {x:0, y:h/2-t/2-g}], p & 0x20); // F drawShape([{x:t+g, y:h/2}, {x:t*1.5+g, y:h/2-t/2}, {x:w-t*1.5-g, y:h/2-t/2}, {x:w-t-g, y:h/2}, {x:w-t*1.5-g, y:h/2+t/2}, {x:t*1.5+g, y:h/2+t/2}], p & 0x40); // G // ドット ctx.beginPath(); ctx.arc(w + t/2, h - t/2, t/2.5, 0, Math.PI * 2); ctx.fillStyle = showDot ? activeColor : inactiveColor; ctx.fill(); } }
- SevenSegmentMulti.qml
import QtQuick Row { id: root spacing: 10 // 入力プロパティ property real reading: 0 property int digits: 4 // 表示する桁数 property int decimalPlaces: 0 // 小数点以下の桁数(0なら整数) property real threshold1: 0 property real threshold2: 0 // デザイン設定(SevenSegに引き継ぐ) property color activeColor: "green" // 基本色(SevenSeg側で上書きも可) property real skewAngle: 8 property real thickness: 16 Repeater { model: root.digits SevenSeg { // 左から数えて何番目の桁かを計算 // index 0 が一番左(大きい桁) readonly property int power: root.digits - index - 1 - root.decimalPlaces value: Math.floor(Math.abs(root.reading) / Math.pow(10, power)) % 10 // 小数点の位置判定 showDot: (root.decimalPlaces > 0 && power === 0) // 共通プロパティの流し込み reading: root.reading threshold1: root.threshold1 threshold2: root.threshold2 skewAngle: root.skewAngle thickness: root.thickness // 桁が足りない場合にゼロを暗くするか消すロジック(オプション) opacity: (power > 0 && Math.pow(10, power) > Math.abs(root.reading) && index < root.digits - root.decimalPlaces - 1) ? 0.2 : 1.0 } } }
- Main.qml
import QtQuick Window { visible: true width: 600; height: 400 color: "black" Column { anchors.centerIn: parent spacing: 40 // CO2濃度 (4桁整数) SevenSegMulti { reading: 1250 digits: 4 threshold1: 1000 threshold2: 2000 } // 温度 (3桁、小数点1位固定) SevenSegMulti { reading: 28.5 digits: 3 decimalPlaces: 1 threshold1: 30 threshold2: 35 } // 湿度 (2桁整数) SevenSegMulti { reading: 55 digits: 2 threshold1: 70 threshold2: 80 } } }
qmlで7セグメント表示.1772503917.txt.gz · 最終更新: by araki
