引用组件
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
Item {
visible: true
width: 400
height: 400
signal qmlSignal(string message)
// 定义接收信息的槽函数
// 定义接收信息的槽函数,并添加 Q_INVOKABLE
// signal messageToQML
property variant receivedData
Demo {
id: speedometer
width: parent.width
height: parent.height
// 设置初始速度值
Component.onCompleted: {
speedometer.value = 80
speedometer.setValue(80);
}
MouseArea{
anchors.fill: parent
onClicked:{
}
}
}
}
组件代码
import QtQuick 2.0
import QtQuick.Controls 2.0
Item {
id: root
width: 300
height: 300
property real value: 0 // 速度值,范围为-100到100
Rectangle {
id: background
width: root.width
height: root.height
color: "#212121" // 黑色主题
border.color: "#424242"
border.width: 2
radius: width / 2
}
Text {
id: valueText
text: Math.round(root.value)
font.pixelSize: 30
font.bold: true
color: "white"
anchors.centerIn: parent
}
Canvas {
id: speedometerCanvas
anchors.fill: parent
onPaint: {
var ctx = getContext("2d");
ctx.reset();
ctx.translate(speedometerCanvas.width / 2, speedometerCanvas.height / 2);
// 绘制速度表盘
ctx.strokeStyle = "#f44336"; // 红色
ctx.lineWidth = 12;
ctx.beginPath();
ctx.arc(0, 0, speedometerCanvas.width / 2 - 20, 0, Math.PI * 2);
ctx.stroke();
// 绘制速度表盘刻度和数字
ctx.lineWidth = 8;
ctx.font = "bold 14px Arial";
ctx.fillStyle = "white";
for (var i = -80; i <= 80; i += 20) {
var angle = ((i / 100) * Math.PI - Math.PI / 2);
var x1 = (speedometerCanvas.width / 2 - 30) * Math.cos(angle);
var y1 = (speedometerCanvas.height / 2 - 30) * Math.sin(angle);
var x2 = (speedometerCanvas.width / 2 - 15) * Math.cos(angle);
var y2 = (speedometerCanvas.height / 2 - 15) * Math.sin(angle);
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
// 绘制刻度数字
var labelX = (speedometerCanvas.width / 2 - 50) * Math.cos(angle);
var labelY = (speedometerCanvas.height / 2 - 50) * Math.sin(angle);
ctx.fillText(i, labelX, labelY);
}
// 绘制速度指针
ctx.strokeStyle = "#00e676"; // 绿色
ctx.lineWidth = 10;
ctx.beginPath();
var pointerAngle = ((root.value / 100) * Math.PI - Math.PI / 2);
var pointerX = (speedometerCanvas.width / 2 - 40) * Math.cos(pointerAngle);
var pointerY = (speedometerCanvas.height / 2 - 40) * Math.sin(pointerAngle);
ctx.moveTo(0, 0);
ctx.lineTo(pointerX, pointerY);
ctx.stroke();
}
}
PropertyAnimation {
id: pointerAnimation
target: root
property: "value"
duration: 1000
easing.type: Easing.OutBounce
}
function setValue(newValue) {
pointerAnimation.to = newValue;
pointerAnimation.running = true;
}
}