ユーザ用ツール

サイト用ツール


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