在Preview窗口中实现以下功能:

- 当鼠标指向热力图上的任意点时
- 根据鼠标位置获取对应的温补后温度值
- 将该温度值显示在窗口标题栏上
This commit is contained in:
zqm
2026-01-19 10:59:40 +08:00
parent a1978f183d
commit d7c035518a
2 changed files with 127 additions and 0 deletions

View File

@@ -1329,6 +1329,8 @@ namespace JoyD.Windows.CS.Toprie
if (_previewForm != null && !_previewForm.IsDisposed)
{
_previewForm.UpdateImage(tempImage);
// 传递温度数据给预览窗口
_previewForm.UpdateTemperatureData(_deviceManager.LastTemperature);
}
// 步骤5同步更新检测配置窗口的实时图像属性
// 创建LastImage的副本并通过UpdateRealTimeImage方法传递给Setting窗口

View File

@@ -6,6 +6,7 @@ using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using JoyD.Windows.CS.Toprie;
namespace JoyD.Windows.CS
{
@@ -25,6 +26,13 @@ namespace JoyD.Windows.CS
private Point _currentDataPoint = new Point(-1, -1);
// 用于保护_currentDataPoint访问的锁对象
private readonly object _dataPointLock = new object();
// 最新的温度数据
private TemperatureData _temperatureData = null;
// 标题栏更新防抖相关字段
private Timer _titleUpdateTimer = null;
private float _pendingTemperature = float.NaN;
private float _currentDisplayedTemperature = float.NaN;
private const int TITLE_UPDATE_DELAY = 50; // 防抖延迟时间(毫秒)
/// <summary>
/// 初始化预览窗口的构造函数
@@ -35,6 +43,11 @@ namespace JoyD.Windows.CS
previewImageBox.MouseMove += PreviewImageBox_MouseMove;
previewImageBox.MouseLeave += PreviewImageBox_MouseLeave;
previewImageBox.Paint += PreviewImageBox_Paint;
// 初始化标题栏更新防抖定时器
_titleUpdateTimer = new Timer();
_titleUpdateTimer.Interval = TITLE_UPDATE_DELAY;
_titleUpdateTimer.Tick += TitleUpdateTimer_Tick;
}
/// <summary>
@@ -73,6 +86,22 @@ namespace JoyD.Windows.CS
}
}
/// <summary>
/// 更新温度数据(线程安全)
/// </summary>
/// <param name="temperatureData">温度数据</param>
public void UpdateTemperatureData(TemperatureData temperatureData)
{
if (this.InvokeRequired)
{
this.Invoke(new Action<TemperatureData>(UpdateTemperatureData), temperatureData);
return;
}
// 更新温度数据
_temperatureData = temperatureData;
}
/// <summary>
/// 窗口关闭时释放资源
/// </summary>
@@ -85,6 +114,14 @@ namespace JoyD.Windows.CS
previewImageBox.MouseLeave -= PreviewImageBox_MouseLeave;
previewImageBox.Paint -= PreviewImageBox_Paint;
// 释放定时器资源
if (_titleUpdateTimer != null)
{
_titleUpdateTimer.Stop();
_titleUpdateTimer.Dispose();
_titleUpdateTimer = null;
}
// 释放图像资源
if (previewImageBox.Image != null)
{
@@ -93,6 +130,63 @@ namespace JoyD.Windows.CS
}
}
// 标题栏更新防抖处理
private void UpdateTitleBarWithDebounce(float temperature)
{
// 只有当温度值实际变化时才更新
// 检查NaN情况如果两者都是NaN认为没有变化
if (float.IsNaN(temperature) && float.IsNaN(_currentDisplayedTemperature))
{
return; // 都是NaN不需要更新
}
// 检查数值变化:如果都是有效数字且差异小于阈值,认为没有变化
if (!float.IsNaN(temperature) && !float.IsNaN(_currentDisplayedTemperature) &&
Math.Abs(temperature - _currentDisplayedTemperature) < 0.1f)
{
return; // 温度值没有显著变化,不需要更新
}
// 保存待更新的温度值
_pendingTemperature = temperature;
// 停止并重新启动定时器
_titleUpdateTimer.Stop();
_titleUpdateTimer.Start();
}
// 定时器Tick事件实际更新标题栏
private void TitleUpdateTimer_Tick(object sender, EventArgs e)
{
// 停止定时器
_titleUpdateTimer.Stop();
// 只有当温度值实际变化时才更新标题栏
// 检查NaN情况如果两者都是NaN认为没有变化
if (float.IsNaN(_pendingTemperature) && float.IsNaN(_currentDisplayedTemperature))
{
return; // 都是NaN不需要更新
}
// 检查数值变化:如果都是有效数字且差异小于阈值,认为没有变化
if (!float.IsNaN(_pendingTemperature) && !float.IsNaN(_currentDisplayedTemperature) &&
Math.Abs(_pendingTemperature - _currentDisplayedTemperature) < 0.1f)
{
return; // 温度值没有显著变化,不需要更新
}
// 更新标题栏
if (!float.IsNaN(_pendingTemperature))
{
this.Text = $"预览 - 温度: {_pendingTemperature:F1}°C";
}
else
{
this.Text = "预览";
}
// 更新当前显示的温度值
_currentDisplayedTemperature = _pendingTemperature;
}
// 鼠标移动事件处理
private void PreviewImageBox_MouseMove(object sender, MouseEventArgs e)
{
@@ -112,6 +206,10 @@ namespace JoyD.Windows.CS
{
_currentDataPoint = dataPoint;
previewImageBox.Invalidate(); // 触发Paint事件重绘
// 获取温度值并使用防抖机制更新标题栏
float temperature = GetTemperatureAtDataPoint(dataPoint);
UpdateTitleBarWithDebounce(temperature);
}
}
}
@@ -124,6 +222,9 @@ namespace JoyD.Windows.CS
{
_currentDataPoint = new Point(-1, -1);
previewImageBox.Invalidate(); // 触发Paint事件重绘
// 使用防抖机制清除标题栏温度显示
UpdateTitleBarWithDebounce(float.NaN);
}
}
@@ -157,6 +258,30 @@ namespace JoyD.Windows.CS
return new Point(x / 2, y / 2);
}
// 获取特定数据点的温度值
private float GetTemperatureAtDataPoint(Point dataPoint)
{
if (_temperatureData == null || _temperatureData.TemperatureMatrix == null)
return float.NaN;
// 原始数据点(x,y)对应TemperatureMatrix[y][x]TemperatureMatrix是[行][列]结构,已包含温补后的温度数据)
int x = dataPoint.X;
int y = dataPoint.Y;
// 确保坐标在有效范围内
// TemperatureMatrix是[行][列]结构,所以:
// - GetLength(0)返回行数
// - GetLength(1)返回列数
// - y对应行索引x对应列索引
if (x >= 0 && x < _temperatureData.TemperatureMatrix.GetLength(1) && // 列索引有效
y >= 0 && y < _temperatureData.TemperatureMatrix.GetLength(0)) // 行索引有效
{
return _temperatureData.TemperatureMatrix[y, x]; // [行][列]访问
}
return float.NaN;
}
// 将原始数据点坐标映射到热力图覆盖区域
private Rectangle GetDataPointCoverageArea(Point dataPoint)
{