用qwt绘制AD波形
来源:互联网 发布:南风知我意2 全文阅读 编辑:程序博客网 时间:2024/04/28 08:56
引子
项目终于快完成了,现在开始整理下代码,总结下,今天先分享下关于使用如何用QWT绘制波形,先把图给贴出来。
关于QWT
以下源于百度百科“QWT全称是Qt Widgets for Technical Applications,是一个基于LGPL版权协议的开源项目,可生成各种统计图。它为具有技术专业背景的程序提供GUI组件和一组实用类,其目标是以基于2D方式的窗体部件来显示数据,数据源以数值,数组或一组浮点数等方式提供,输出方式可以是Curves(曲线),Slider(滚动条),Dials(圆盘),Compasses(仪表盘)等等。该工具库基于Qt开发,所以也继承了Qt的跨平台特性。”
我使用的是qwt-6.0.0-rc5,可以到官网下载http://qwt.sourceforge.net/,具体的安装和集成过程可以参照http://www.cuteqt.com/blog/?p=994这个贴子。 源码
“AdPlot.h”
1: #ifndef ADPLOT_H2: #define ADPLOT_H3: 4: #include <QWidget>5: #include <qwt_plot_curve.h>6: #include <qfile.h>7: #include <qwt_plot_magnifier.h>8: 9: namespace Ui {10: class AdPlot;11: }
12: 13: class AdPlot : public QWidget14: {
15: Q_OBJECT
16: 17: public:18: explicit AdPlot(QWidget *parent = 0);19: //要绘制的AD数据,X-时间,Y-电压值20: void readAdData(QVector< double > &xData,21: QVector< double > &yData);22: void setTitleString(QString title);23: void setTimerStop();24:25: ~AdPlot();
26: public slots:27: //节点打开的AD数据的文件名28: void setFileName(QString filename);29: //绘制AD数据30: void plotAdCurve();31: private:32: Ui::AdPlot *ui;
33: QwtPlotCurve *p_adplot;
34: QVector< double > xData;35: QVector< double > yData;36: QFile *localFile;
37: //文件偏移量38: qint64 offset;
39: double time;40: QString m_filename;
41: QwtPlotMagnifier *PM;
42: //当前X轴最大的范围43: int xMaxScale;44:45: QTimer *adPlotTimer;
46:47: QString m_title;
48: };
49: 50: #endif // ADPLOT_H
头文件没什么好说的,说明一下offset这个变量,它是用来保存当前的读取到的文件位置,而xData和yData分别储存时间和电压值。 “AdPlot.cpp”
1: #include "adplot.h"2: #include "ui_adplot.h"3: #include <QtGui/QApplication>4: #include <qapplication.h>5: #include <qlayout.h>6: #include <qlabel.h>7: #include <qpainter.h>8: #include <qwt_plot_layout.h>9: #include <qwt_plot_curve.h>10: #include <qwt_scale_draw.h>11: #include <qwt_scale_widget.h>12: #include <qwt_legend.h>13: #include <qwt_legend_item.h>14: #include <QTime>15: #include <qtimer.h>16: #include <QMessageBox>17: #include <qcolor.h>18: #include <qwt_plot_zoomer.h>19: 20: class TimeScaleDraw: public QwtScaleDraw21: {
22: public:23: TimeScaleDraw(const QTime &base):24: baseTime(base)
25: {
26: }
27: 28: virtual QwtText label(double v) const29: {
30: QTime upTime = baseTime.addSecs((int)v);31: return upTime.toString();32: }
33: 34: private:35: QTime baseTime;
36: };
37: 38:39: AdPlot::AdPlot(QWidget *parent) :
40: QWidget(parent),
41: ui(new Ui::AdPlot)42: {
43: ui->setupUi(this);44: ui->qwtPlot->setAutoReplot(false);
45: QTime curTime;
46: curTime = curTime.currentTime();
47: 48: 49: 50: QwtLegend *legend = new QwtLegend;51: legend->setItemMode(QwtLegend::CheckableItem);
52: //ui->qwtPlot->insertLegend(legend, QwtPlot::RightLegend);53: ui->qwtPlot->setAxisTitle(QwtPlot::xBottom, " System Uptime [h:m:s]");54: ui->qwtPlot->setAxisScaleDraw(QwtPlot::xBottom,
55: new TimeScaleDraw(curTime));56: ui->qwtPlot->setAxisScale(QwtPlot::xBottom, 0, xMaxScale = 5);
57: ui->qwtPlot->setAxisLabelAlignment(QwtPlot::xBottom, Qt::AlignLeft | Qt::AlignBottom);
58:59: QwtScaleWidget *scaleWidget = ui->qwtPlot->axisWidget(QwtPlot::xBottom);
60: const int fmh = QFontMetrics(scaleWidget->font()).height();61: scaleWidget->setMinBorderDist(0, fmh / 2);
62: 63: ui->qwtPlot->setAxisTitle(QwtPlot::yLeft, "V");64: ui->qwtPlot->setAxisScale(QwtPlot::yLeft, 0, 3);
65: p_adplot = new QwtPlotCurve();66: QColor c = Qt::red;
67: c.setAlpha(150);
68: p_adplot->setPen(c);
69:70: p_adplot->attach(ui->qwtPlot);
71: //PM = new QwtPlotMagnifier(ui->qwtPlot->canvas());72: QwtPlotZoomer* zoomer = new QwtPlotZoomer( ui->qwtPlot->canvas() );73: zoomer->setRubberBandPen( QColor( Qt::black ) );
74: zoomer->setTrackerPen( QColor( Qt::black ) );
75: zoomer->setMousePattern(QwtEventPattern::MouseSelect2,Qt::RightButton, Qt::ControlModifier );
76: zoomer->setMousePattern(QwtEventPattern::MouseSelect3,Qt::RightButton );
77: time = 0.0;
78: adPlotTimer = new QTimer();79: adPlotTimer->start(100);
80: connect(adPlotTimer, SIGNAL(timeout()),
81: this, SLOT(plotAdCurve()));82: offset = 0;
83: }
84:85: AdPlot::~AdPlot()
86: {
87: delete ui;88: }
89: 90: void AdPlot::readAdData(QVector<double> &xData, QVector<double> &yData)91: {
92: if(!m_filename.isEmpty())93: {
94: localFile = new QFile(m_filename); //用户端的IP地址+端口号作为文件名95: if (!localFile->open(QFile::ReadOnly ))96: {
97: QMessageBox::warning(0, tr("应用程序"),98: tr("无法读取文件 %1:\n%2.")99: .arg(m_filename)
100: .arg(localFile->errorString()));
101: return;102: }
103: QByteArray adData;
104: if (!localFile->atEnd())105: {
106: if (offset == 0)107: {
108: adData = localFile->read(26);
109: qDebug()<<adData;
110: offset += 26;
111: adData.resize(0);
112: return;113: }
114: 115: if (localFile->seek(offset))116: {
117:118: adData = localFile->read(32*2);
119: if (adData.count() == 32*2)120: {
121: for (int count=0; count<32; count++)122: {
123: char lowbits = adData.at(count*2);124: char highbits = adData.at(count*2 + 1);125: short temp = lowbits+highbits*256;126: yData.append(((float)temp)*3300/4096/1000);127: xData.append(time);
128: time += 0.005; //5ms一个数据129: }
130: offset += 32*2;
131: }
132: }
133: }
134: }
135:136: }
137: 138: void AdPlot::plotAdCurve()139: {
140: readAdData(xData,yData);
141: p_adplot->setSamples(xData,yData);
142: if (!xData.empty())143: {
144: if (xData.last() >= xMaxScale)145: {
146: xMaxScale *= 2;
147: ui->qwtPlot->setAxisScale(QwtPlot::xBottom, 0, xMaxScale);
148: }
149: }
150: p_adplot->attach(ui->qwtPlot);
151: ui->qwtPlot->replot();
152: adPlotTimer->start(100);
153: 154:155: }
156: 157: void AdPlot::setFileName(QString filename)158: {
159: m_filename = filename;
160: }
161: 162: void AdPlot::setTitleString(QString title)163: {
164: m_title = title;
165: ui->qwtPlot->setTitle(m_title);
166: }
167: 168: void AdPlot::setTimerStop()169: {
170: adPlotTimer->stop();
171: }
首先:
说一下TimeScaleDraw这个类,它继承了QwtScaleDraw的类,其实就是一个抽象的一个刻度类,具体的函数说明可以参考说明手册.
对了,ui界面里没什么东西,就一个qwtplot的控件.
接着初始化坐标轴:
- void setAxisTitle (int axisId, const QString &) 用来设置坐标轴名字,第一个参数是QWT定义的坐标轴ID,即yLeft,yRight,xBottom和xTop.
- void setAxisScaleDraw (int axisId, QwtScaleDraw *)用来设置坐标轴刻度,第一个参数同上,第二个参数就是我们刚才定义的TimeScaleDraw;
- void setAxisScale (int axisId, double min, double max, double step=0)也是设置刻度的,第一个参数同上,第二参数是刻度的最小值,第三个参数是刻度的最大值,最后一个是步长.
然后定义一个曲线QwtPlotCurve:
QwtPlotCurve,它的功能就是输入一系列的X,Y的值,然后绘制出曲线,当然,曲线的color,style那些是可以自己设置的.
缩放曲线(PS:这点就体现了QWT的强大之处):
QwtPlotZoomer,简单的一个类,简单的只个设置就可以缩放曲线,谁用谁知道啊.
定时器完成曲线的重绘:
adPlotTimer = new QTimer();
adPlotTimer->start(100);
connect(adPlotTimer, SIGNAL(timeout()), this, SLOT(plotAdCurve()));
因为所用的AD是400K的,算了一下,大概160ms以下就能满足了.
读取AD数据:
因为服务器接收到的AD数据是保存在文件中的,而且是实时保存(也就是将Client接收的数据保存到文件的同时将此文件中的数据绘制出来).所以设置了一个文件偏移量,而已此文件的前26字节是采集的时间信息,所以跳过.
又因为用的是AD是12位的,Client采用一个short类型来保存数据,而已每次传输32个AD数据,所以在计算AD数据前要确保文件已经有了32个AD数据,即64字节的数据.
绘制AD数据:
void setSamples (const QVector< double > &xData, const QVector< double > &yData)完成数据的设置.
此函数重点在于时间轴的拉长:
if (xData.last() >= xMaxScale) {xMaxScale *= 2;ui->qwtPlot->setAxisScale(QwtPlot::xBottom, 0, xMaxScale);}总结:
qwt的确一个优秀的第三方库,使用也不复杂,而已有详细的文档说明,还有很多例子,不过都是英文的,慢慢看吧.
- 用qwt绘制AD波形
- 用qwt绘制AD波形
- 用qwt绘制AD波形(转载)
- 用qwt绘制按秒采集数据波形图
- Qt下利用QWT绘制波形图
- QWT绘制巴图
- 绘制wav波形图
- 2. 绘制波形图
- java绘制波形图
- android 录音绘制波形
- 录音波形绘制代码
- android 录音绘制波形
- C#窗体绘制波形
- C#用serialPort和chart控件实现简单波形绘制
- 在Android上用Canvas绘制音频波形图
- 使用Qwt绘制历史曲线
- java绘制音频波形图
- android音频波形图绘制
- 关于web页面播放声音
- 个人电脑配置外网可以访问服务器
- 深入浅出Swing事件分发线程
- cef chromium scrollbar--google浏览器框架自定义滚动条
- linux socket和UDP 源端口绑定
- 用qwt绘制AD波形
- css实现文字竖排
- return this.each(function(){})
- 4.链式二叉树_静态_遍历
- Android中shape的使用
- java虚拟机指令笔记(待补充)
- 批出理命令代码
- C# 中读取excel文件
- Android学习笔记进阶20之得到图片的缩略图