添加OpenCv

This commit is contained in:
2025-09-15 22:28:43 +08:00
parent c0593df9e1
commit 94282fb1d9
423 changed files with 622349 additions and 97439 deletions

View File

@@ -0,0 +1,162 @@
#include "CurvePlotWidget.h"
#include <QPainter>
#include <QtMath>
#include <limits>
#include <QDebug>
#include <QTime>
CurvePlotWidget::CurvePlotWidget(QWidget *parent) : QWidget(parent)
{
setMinimumSize(300, 200);
}
void CurvePlotWidget::setTimeRange(double secs)
{
m_tRange = qMax(secs, 1.0);
m_xMax = qMax(200, int(width() / 2));
for (auto &c : m_curves) {
c.tBuf.resize(m_xMax);
c.yBuf.resize(m_xMax);
c.head = 0;
}
update();
}
void CurvePlotWidget::initCurve(int id, const CurveCfg &cfg)
{
Curve c;
c.cfg = cfg;
// 确保阈值有效
Q_ASSERT(cfg.thWarning < cfg.thFault);
Q_ASSERT(cfg.thFault <= cfg.yMax);
c.tBuf.resize(m_xMax);
c.yBuf.resize(m_xMax);
c.tBuf.fill(std::numeric_limits<double>::quiet_NaN());
c.yBuf.fill(std::numeric_limits<double>::quiet_NaN());
c.head = 0;
m_curves.insert(id, c);
}
void CurvePlotWidget::clearAllCurves()
{
m_curves.clear();
m_t0set = false;
update();
}
void CurvePlotWidget::appendPoint(int curveId, double timeStamp, double yValue)
{
if (!m_curves.contains(curveId)) return;
Curve &c = m_curves[curveId];
if (!m_t0set) {
m_t0 = timeStamp;
m_t0set = true;
}
double t = timeStamp - m_t0;
c.tBuf[c.head] = t;
c.yBuf[c.head] = yValue;
c.head = (c.head + 1) % m_xMax;
update();
}
void CurvePlotWidget::paintEvent(QPaintEvent *)
{
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
QRectF plotRect(m_leftMargin, m_topMargin,
width() - m_leftMargin - m_rightMargin,
height() - m_topMargin - m_bottomMargin);
/* ---------- 1. 顶部图例 ---------- */
int legendX = m_leftMargin + 5;
int legendY = m_topMargin - 15;
for (const auto &c : m_curves) {
p.setPen(QPen(c.cfg.normal, 2));
p.drawLine(legendX, legendY, legendX + 15, legendY);
p.setPen(QPen(Qt::white));
p.drawText(legendX + 20, legendY + 4, c.cfg.name);
legendX += 20 + p.fontMetrics().horizontalAdvance(c.cfg.name) + 15;
}
/* ---------- 2. 坐标轴 ---------- */
p.setPen(Qt::white);
/* Y 轴刻度 */
if (!m_curves.isEmpty()) {
const Curve &c = *m_curves.begin();
double yMax = c.cfg.yMax;
for (int i = 0; i <= 4; ++i) {
double y = yMax * i / 4.0;
QString txt = QString::number(y, 'f', 1);
int ty = int(plotRect.bottom() - i * plotRect.height() / 4.0);
p.drawText(5, ty + 4, txt);
}
}
/* ---------- X 轴刻度(真实时钟) ---------- */
// 当前这一帧可见窗口的绝对时间范围
double tLeftEpoch = QDateTime::currentDateTime().toSecsSinceEpoch() - m_tRange;
double tRightEpoch = QDateTime::currentDateTime().toSecsSinceEpoch();
for (int i = 0; i <= 4; ++i) {
double tEpoch = tLeftEpoch + m_tRange * i / 4.0; // 绝对秒
QDateTime tm = QDateTime::fromSecsSinceEpoch(qint64(tEpoch)); // 真实时钟
QString txt = tm.toString("hh:mm:ss");
int tx = int(plotRect.left() + i * plotRect.width() / 4.0);
p.drawText(tx - 25, height() - 5, txt);
}
/* ---------- 4. 曲线 ---------- */
for (const auto &c : m_curves) {
if (m_xMax <= 1) continue;
// 改成同时缓存 QPointF 和 对应的 y 值
struct Pt {
QPointF pos;
double y;
};
QVector<Pt> pts;
pts.reserve(m_xMax);
for (int i = 0; i < m_xMax; ++i) {
int idx = (c.head + i) % m_xMax;
double t = c.tBuf[idx];
double y = c.yBuf[idx];
if (std::isnan(t) || std::isnan(y))
continue;
pts.append({mapToWidget(t, y, c), y});
}
if (pts.size() < 2) continue;
// 逐段画线,颜色直接用 pts[k].y
for (int k = 0; k < pts.size() - 1; ++k) {
double y = pts[k].y;
int level = 0;
if (y >= c.cfg.thFault) level = 2;
else if (y >= c.cfg.thWarning) level = 1;
QColor col = level == 0 ? c.cfg.normal
: level == 1 ? c.cfg.warning
: c.cfg.fault;
p.setPen(QPen(col, 2));
p.drawLine(pts[k].pos, pts[k + 1].pos);
}
}
}
QPointF CurvePlotWidget::mapToWidget(double t, double y, const Curve &c) const
{
QRectF plotRect(m_leftMargin, m_topMargin,
width() - m_leftMargin - m_rightMargin,
height() - m_topMargin - m_bottomMargin);
double x = plotRect.left() + (t / m_tRange) * plotRect.width();
double norm = qBound(0.0, y / c.cfg.yMax, 1.0);
double wy = plotRect.bottom() - norm * plotRect.height();
return QPointF(x, wy);
}
void CurvePlotWidget::resizeEvent(QResizeEvent *)
{
setTimeRange(m_tRange); // 按新宽度重新计算点数
}