上位機數據可視化:使用QtCharts繪制波形圖

工程配置

CMake文件

find_package(Qt5 COMPONENTS Charts REQUIRED)target_link_libraries(zhd-desktop PRIVATE Qt5::Charts)

包含頭文件以及名稱空間(這個很重要,沒有包含名稱空間編譯器會提示找不到相關的類型)

#include <QtCharts>using namespace QtCharts;

初始化

初始化Chart

// 創建圖表
QChart *chart = new QChart();
chart->setTitle("Valve Data");// 隱藏圖例
chart->legend()->setVisible(false);// 創建圖表視圖
QChartView *chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);QHBoxLayout *hLayout = new QHBoxLayout(ui->view);
hLayout->addWidget(chartView);
hLayout->setContentsMargins(0, 0, 0, 0);

波形

每一道波形就是一個QLineSeries,每個QLineSeries都要和X軸和Y軸進行綁定

m_temperature = new QLineSeries();
m_temperature->setColor(Qt::red);
m_temperature->setPointsVisible(true);m_pressure = new QLineSeries();
m_pressure->setColor(Qt::blue);
m_pressure->setPointsVisible(true);m_position = new QLineSeries();
m_position->setColor(Qt::black);
m_position->setPointsVisible(true);m_pressureSetpt = new QLineSeries();
m_pressureSetpt->setColor(Qt::darkYellow);
m_pressureSetpt->setPointsVisible(true);

為了使波形更有區分度,需要配置不同的顏色,建議跟Y軸刻度的顏色保持一致,特別是軸比較多的情況下

void setAxisColor(QAbstractAxis *axis, const QColor &color)
{axis->setGridLineColor(color);axis->setLinePenColor(color);axis->setLabelsColor(color);axis->setTitleBrush(color);
}

X軸

X軸一般是時間軸,時分秒格式:hh:mm:ss

QDateTimeAxis *timeAxis = new QDateTimeAxis();
timeAxis->setTitleText("Time");
timeAxis->setFormat("hh:mm:ss");
chart->addAxis(timeAxis, Qt::AlignBottom);
series1->attachAxis(timeAxis);
series2->attachAxis(timeAxis);

Y軸

Y軸:左側和右側都可以添加刻度尺

// 左側刻度尺
QValueAxis *pressureSetpt = new QValueAxis();
pressureSetpt->setTitleText("Pressure Setpt (Torr)");
pressureSetpt->setRange(0, 25);
chart->addAxis(pressureSetpt, Qt::AlignLeft);
series1->attachAxis(pressureSetpt);QValueAxis *pressure = new QValueAxis();
pressure->setTitleText("Pressure (Torr)");
pressure->setRange(0, 25);
chart->addAxis(pressure, Qt::AlignLeft);
series1->attachAxis(pressure);// 右側刻度尺
QValueAxis *driverTemperature = new QValueAxis();
driverTemperature->setTitleText("Driver temperature");
driverTemperature->setRange(0, 100);
chart->addAxis(driverTemperature, Qt::AlignRight);
series2->attachAxis(driverTemperature);QValueAxis *positionAxis = new QValueAxis();
positionAxis->setTitleText("Position (%)");
positionAxis->setRange(0, 100);
chart->addAxis(positionAxis, Qt::AlignRight);
series2->attachAxis(positionAxis);

繪圖

實時繪制波形點:往QLineSeries里邊添加數據,用append接口

QDateTime currentTime = QDateTime::currentDateTime();
if(m_resumePause) {m_timeAxis->setRange(currentTime.addSecs(-10), currentTime);
}if(m_channels[0]) {m_pressure->append(currentTime.toMSecsSinceEpoch(), pressure);if (m_pressure->count() > m_max) {m_pressure->remove(0);}
}if(m_channels[1]) {m_position->append(currentTime.toMSecsSinceEpoch(), position);if (m_position->count() > m_max) {m_position->remove(0);}
}if(m_channels[2]) {m_pressureSetpt->append(currentTime.toMSecsSinceEpoch(), pressureSetpt);if (m_pressureSetpt->count() > m_max) {m_pressureSetpt->remove(0);}
}if(m_channels[3]) {m_temperature->append(currentTime.toMSecsSinceEpoch(), valveTemperature);if (m_temperature->count() > m_max) {m_temperature->remove(0);}
}

注意事項

1.時間軸要實時移動到正確的時間窗口范圍

2.QLineSeries波形點之后到達一定的數據量需要刪除一些點以確保buffer不會寫爆(頻繁申請內存導致卡頓)

進階

QtCharts自帶的時間軸比較丑陋,如果想要定制的話,可以參考以下方法進行樣式修改

  1. 自定義QValueAxis作為X軸
  2. 捕獲QValueAxis::rangeChanged信號,獲取QChartView里邊的scene,同時也可以獲取到刻度的左右邊界minmax
  3. 刪除scene(QGraphicsScene)里邊的所有items,即原有的刻度不要了
  4. QGraphicsScene即基礎上畫刻度,每一個刻度就是一個QGraphicsLineItem

代碼參考

// 動態修改 X 軸標簽為時間格式,并繪制刻度線
QObject::connect(axisX, &QValueAxis::rangeChanged, [axisX, chartView](qreal min, qreal max) {QGraphicsScene *scene = chartView->scene();// 檢查 min 和 max 是否有效if (qIsNaN(min) || qIsNaN(max) || qIsInf(min) || qIsInf(max)) {// qWarning() << "Invalid min or max value:" << min << max;return;}// 檢查 plotArea 是否有效if (chartView->chart()->plotArea().width() <= 0 || chartView->chart()->plotArea().height() <= 0) {//  qWarning() << "Invalid plot area size";return;}// 清除舊的標簽和刻度線for (QGraphicsItem *item : scene->items()) {if (item->data(0).toString() == "custom_label" || item->data(0).toString() == "custom_line") 		{scene->removeItem(item);delete item;}}// 生成 10 個刻度int tickCount = 10;  // 總共 10 個刻度qreal tickInterval = (max - min) / (tickCount - 1);  // 計算刻度間隔for (int i = 0; i < tickCount; ++i) {qreal value = min + i * tickInterval;// 檢查 value 是否有效if (qIsNaN(value) || qIsInf(value)) {// qWarning() << "Invalid value:" << value;continue;}QDateTime dateTime = QDateTime::fromSecsSinceEpoch(value);// 計算刻度線的位置qreal x = chartView->chart()->plotArea().left() +(value - min) / (max - min) * chartView->chart()->plotArea().width();// 檢查 x 是否有效if (qIsNaN(x) || qIsInf(x)) {// qWarning() << "Invalid x coordinate:" << x;continue;}// 只在偶數刻度繪制時間標簽和黑線if (i % 2 == 0) {// 繪制時間標簽QString label = dateTime.toString("hh:mm:ss");QGraphicsTextItem *textItem = scene->addText(label);qreal textWidth = textItem->boundingRect().width();  // 獲取標簽寬度qreal textHeight = textItem->boundingRect().height();  // 獲取標簽高度// 調整標簽位置,使其居中對齊刻度線textItem->setPos(x - textWidth / 2, chartView->chart()->plotArea().bottom() + 10);textItem->setData(0, "custom_label");  // 標記為自定義標簽// 繪制黑線qreal lineLength = 10;  // 刻度線長度QGraphicsLineItem *lineItem = scene->addLine(x, chartView->chart()->plotArea().bottom(),x, chartView->chart()->plotArea().bottom() + lineLength,QPen(Qt::black));lineItem->setData(0, "custom_line");  // 標記為自定義刻度線}}
});

打包

軟件打包,需要添加Qt5Charts這個dll

Qt5Charts.dll

版權

版權問題,商用的話可能會被Qt請喝茶
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/72663.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/72663.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/72663.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

S32K144入門筆記(十三):LPIT的API函數解讀

目錄 1. SDK中的函數 2. API函數的釋義 2.1 獲取默認參數 2.2 初始化 2.3 啟動與停止 2.4 計數值的設置于讀取 2.5 中斷API 1. SDK中的函數 在使用SDK的非抽象驅動函數時&#xff0c;函數的定義與聲明在文件lpit_driver.c和lpit_driver.h中&#xff0c;一共有19個函數&a…

CSS - Pseudo-classes(偽類選擇器)

目錄 一、介紹二、常用種類三、案例實現案例一&#xff1a;a標簽使用link/visited/hover/active案例二&#xff1a;表單元素使用focus/disabled案例三、通過其余偽類實現元素靈活選中 一、介紹 CSS 偽類&#xff08;Pseudo-classes&#xff09; 用于定義元素的特定狀態或結構位…

http proxy的原理是什么

Http代理的原理 代理服務器會自動提取請求數據包中的HTTP請求數據發送給服務端&#xff0c;并將服務端的HTTP響應數據轉發給發送請求的客戶端&#xff0c;HTTP代理服務器使用的端口通常是8080。 對于Web客戶端來說&#xff0c;代理扮演的服務器角色&#xff0c;接收請求&…

Ubuntu22.04虛擬機里安裝Yolov8流程

1. 安裝pytorch sudo apt install nvidia-cuda-toolkit nvcc --version # 官方適配地址&#xff1a;https://download.pytorch.org/whl/torch/import torch print(torch.__version__) print(torch.cuda.is_available())2. 安裝環境 # cuDNN 安裝&#xff1a;https://develop…

神經網絡微調技術解析

神經網絡微調技術 微調&#xff08;Fine-tuning&#xff09;是遷移學習的核心技術&#xff0c;通過在預訓練模型基礎上調整參數&#xff0c;使其適應特定任務或領域。以下從傳統方法、參數高效微調&#xff08;PEFT&#xff09;、新興技術三個維度展開&#xff0c;覆蓋主流技術…

Spring 聲明式事務管理

Spring 編程的方式實現事務管理&#xff0c;這樣太過麻煩&#xff0c;需要在每個方法上面加上相應的事務處理操作&#xff0c;聲明式事務處理能夠很好的解決這個問題&#xff0c;比如通過tx命名空間&#xff0c;這樣只需要配置就可以檢測到相關的方法&#xff0c;或者是通過tra…

電機控制常見面試問題(十五)

文章目錄 一、電機氣隙二、電氣時間三.電機三環控制詳解四.驅動板跳線意義五.電機開環自檢 一、電機氣隙 電機氣隙是定子和轉子之間的空隙&#xff0c;防止釘子轉子運轉時物理接觸&#xff0c;此外&#xff0c;氣隙是磁路的重要環節&#xff0c;磁場需通過氣隙傳遞能量&#x…

代碼隨想錄算法訓練營第六十五天| 圖論10

Bellman_ford 隊列優化算法&#xff08;又名SPFA&#xff09; 代碼隨想錄 import collectionsdef main():n, m map(int, input().strip().split())edges [[] for _ in range(n 1)]for _ in range(m):src, dest, weight map(int, input().strip().split())edges[src].append…

Chat2DB:讓數據庫管理像聊天一樣簡單

數據庫工具的痛點與破局 在數據爆炸的時代&#xff0c;數據庫管理工具已成為企業高效運營的剛需。然而&#xff0c;傳統工具如Navicat、DBeaver雖功能強大&#xff0c;卻讓非技術人員和SQL新手望而卻步。復雜的界面、繁瑣的手動操作、晦澀的語法規則&#xff0c;成為橫亙在數據…

Navicat for Snowflake 震撼首發,激活數據倉庫管理全新動能

近日&#xff0c;Navicat 家族迎來了一位全新成員 — Navicat for Snowflake。Snowflake 是一款基于云架構的現代數據倉庫解決方案&#xff0c;以其彈性擴展、高性能和易用性著稱。這次首發的Navicat for Snowflake 專為簡化 Snowflake 數據庫管理任務而精心打造。它憑借其直觀…

【項目合集】智能語音小車-微信小程序控制

功能需求&#xff1a; 車子檢測環境溫度、濕度&#xff0c;上報 APP、WEB 端顯示實時數據可通過 APP 控制小車前進、左轉、右轉可通過語音控制小車前進后退車上一個 LED 燈&#xff0c;可通過 WEB、小程序控制在 APP、WEB 上均可注冊登錄 硬件清單 硬件 功能 備注 ESP32 …

人工智能與人的智能,改變一生的思維模型分享【4】決策樹

決策樹&#xff08; DECISION TREE&#xff09; 一般由一個決策圖和若干可能的結果組成。是一種通過羅列解題的關鍵步驟以及各步驟發生的條件和結果&#xff0c;由此來創建到達目標的規劃。 我們很早就知道有一個方法&#xff0c;叫做當你苦悶、糾結的時候&#xff0c;把你的所…

利用余弦相似度在大量文章中找出抄襲的文章

我前面的2篇文章分別講了如果利用余弦相似度來判斷2篇文章的相似度&#xff0c;來確定文章是否存在抄襲&#xff0c;和余弦相似度的原理&#xff0c;即余弦相似度到底是怎么來判斷文章的相似性高低的等等。這一篇再說下&#xff0c;對于文章字數多和大量文章時&#xff0c;如果…

設計模式-對象創建

對象創建 前言1. Factory Method1.1 模式介紹1.2 模式代碼1.2.1 問題代碼1.2.2 重構代碼 1.3 模式類圖1.4 要點總結 2. Abstract Factory2.1 模式介紹2.2 模式代碼2.2.1 問題代碼2.2.2 重構代碼 2.3 模式類圖2.4 要點總結 3. Prototype3.1 模式介紹3.2 模式代碼3.3 模式類圖3.4…

SQLAlchemy系列教程:批量插入數據

高效地批量插入數據對于應用程序的性能至關重要。SQLAlchemy為批處理操作提供了幾種機制&#xff0c;可以最大限度地減少開銷并加快數據庫事務時間。在本指南中&#xff0c;我們將探討如何使用SQLAlchemy執行批量插入&#xff0c;包括從基礎技術到高級技術。 搭建環境 在開始之…

V2X驗證

1. 標準和規范驗證 歐洲對 DSRC 和 V2X 系統有一系列的標準和規范,主要由 ETSI (European Telecommunications Standards Institute) 和 IEEE 等組織制定。驗證通常包括以下標準和規范: ETSI EN 302 571:這是DSRC在歐洲的主要標準,規定了DSRC系統的技術要求和操作條件。ET…

openEuler系統遷移 Docker 數據目錄到 /home,解決Docker 臨時文件占用大問題

根據錯誤信息 write /var/lib/docker/tmp/...: no space left on device&#xff0c;問題的根源是 根分區&#xff08;/&#xff09;的磁盤空間不足&#xff0c;而非 /home 分區的問題。以下是詳細解釋和解決方案&#xff1a; 問題原因分析 Docker 臨時文件占用根分區空間&…

Matlab 四分之一車輛被動懸架和模糊pid控制對比

1、內容簡介 Matlab 183-四分之一車輛被動懸架和模糊pid控制對比 可以交流、咨詢、答疑 2、內容說明 略 3.1 車輛多自由度模型建立 對于車輛動力學&#xff0c;一般都是研究其懸架系統&#xff0c;懸架系統由輪胎&#xff0c;輪胎空氣&#xff0c;彈簧&#xff0c;減震器和…

LabVIEW旋轉設備狀態在線監測系統

為了提高大型旋轉設備如電機和水泵的監控效率和故障診斷能力&#xff0c;用LabVIEW軟件開發了一套實時監測與故障診斷系統。該系統集成了趨勢分析、振動數據處理等多項功能&#xff0c;可實時分析電機電流、壓力、溫度及振動數據&#xff0c;以早期識別和預報故障。 ? 項目背…

微前端 無界wujie

開發環境配置: Node.js 版本 < 18.0.0 pnpm 腳手架示例模版基于 pnpm turborepo 管理項目 如果您的當前環境中需要切換 node.js 版本, 可以使用 nvm or fnm 進行安裝. 以下是通過 nvm 或者nvs 安裝 Node.js 16 LTS 版本 nvs安裝教程 https://blog.csdn.net/glorydx/artic…