9 changed files with 44149 additions and 113 deletions
-
10CMakeLists.txt
-
35496libzqt/qcustomplot.cpp
-
7737libzqt/qcustomplot.h
-
446libzqt/widgetplot2d.cpp
-
54libzqt/widgetplot2d.h
-
351libzqt/widgetplot2d.ui
-
132mainwindow.cpp
-
30mainwindow.ui
-
6src/main.cpp
35496
libzqt/qcustomplot.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
7737
libzqt/qcustomplot.h
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,446 @@ |
|||||
|
#include "widgetplot2d.h"
|
||||
|
|
||||
|
#include <QDebug>
|
||||
|
|
||||
|
#include "ui_widgetplot2d.h"
|
||||
|
|
||||
|
WidgetPlot2D::WidgetPlot2D(QWidget* parent) : QWidget(parent), ui(new Ui::WidgetPlot2D), time(QTime::currentTime()) { |
||||
|
ui->setupUi(this); |
||||
|
// QCP绘图初始化
|
||||
|
initQCP(); |
||||
|
// 初始化控件
|
||||
|
initWidget(); |
||||
|
// 上下分裂器
|
||||
|
ui->splitter->setStretchFactor(0, 20); |
||||
|
ui->splitter->setStretchFactor(1, 1); |
||||
|
// 左右分裂器
|
||||
|
ui->splitter1->setStretchFactor(0, 10); |
||||
|
ui->splitter1->setStretchFactor(1, 3); |
||||
|
// 滚动条设置
|
||||
|
ui->horizontalScrollBar->setRange(0, 0); |
||||
|
// 拖动水平滚动条,图幅跟随变化
|
||||
|
connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(horzScrollBarChanged(int))); |
||||
|
// 默认坐标范围
|
||||
|
ui->customPlot->yAxis->setRange(-20, 20); |
||||
|
ui->customPlot->replot(); |
||||
|
} |
||||
|
|
||||
|
WidgetPlot2D::~WidgetPlot2D() { delete ui; } |
||||
|
/* 初始化曲线名称 */ |
||||
|
void WidgetPlot2D::initGraphName(QStringList name) { |
||||
|
//----------------------------------------------------------------------------------------//
|
||||
|
// 设置表头
|
||||
|
ui->treeWidget->setHeaderLabels(QStringList() << "名称" |
||||
|
<< "值" |
||||
|
<< "颜色"); |
||||
|
ui->treeWidget->header()->setVisible(true); |
||||
|
// 表头文字中间对齐
|
||||
|
QTreeWidgetItem* header = ui->treeWidget->headerItem(); |
||||
|
header->setTextAlignment(0, Qt::AlignLeft); |
||||
|
header->setTextAlignment(1, Qt::AlignLeft); |
||||
|
header->setTextAlignment(2, Qt::AlignLeft); |
||||
|
// 设置列宽
|
||||
|
ui->treeWidget->setColumnWidth(0, 100); |
||||
|
ui->treeWidget->setColumnWidth(1, 90); |
||||
|
ui->treeWidget->setColumnWidth(2, 30); |
||||
|
// 表头顺序是否可以拖动改变
|
||||
|
ui->treeWidget->header()->setCascadingSectionResizes(true); |
||||
|
// 被选部分是否高亮显示
|
||||
|
ui->treeWidget->header()->setHighlightSections(false); |
||||
|
// 最后一个区域是否占满表格余下的所有部分
|
||||
|
ui->treeWidget->header()->setStretchLastSection(true); |
||||
|
// 列表的列数
|
||||
|
ui->treeWidget->setColumnCount(3); |
||||
|
//----------------------------------------------------------------------------------------//
|
||||
|
for (int i = 0; i < name.length(); i++) { |
||||
|
// 添加曲线列表项
|
||||
|
QTreeWidgetItem* item = new QTreeWidgetItem; |
||||
|
ui->treeWidget->addTopLevelItem(item); |
||||
|
//----------------------------------------------------------------------------------------//
|
||||
|
// 向曲线列表项第一列添加曲线是否可见复选框
|
||||
|
QCheckBox* isShowCheckBox = new QCheckBox(name.at(i)); |
||||
|
isShowCheckBox->setChecked(true); |
||||
|
connect(isShowCheckBox, SIGNAL(stateChanged(int)), this, SLOT(changeGraphVisible())); |
||||
|
ui->treeWidget->setItemWidget(item, 0, isShowCheckBox); |
||||
|
isShowCheckBoxVector.append(isShowCheckBox); |
||||
|
//----------------------------------------------------------------------------------------//
|
||||
|
// 向曲线列表项第二列添加曲线数值标签
|
||||
|
QLabel* valueLabel = new QLabel("0"); |
||||
|
QFont font("Courier"); |
||||
|
valueLabel->setFont(font); |
||||
|
// valueLabel->setAlignment(Qt::AlignHCenter);
|
||||
|
ui->treeWidget->setItemWidget(item, 1, valueLabel); |
||||
|
valueLabelVector.append(valueLabel); |
||||
|
//----------------------------------------------------------------------------------------//
|
||||
|
// 向曲线列表项第三列添加曲线颜色按钮,点击该按钮弹出颜色选择框,选择曲线颜色
|
||||
|
QPushButton* GraphColorPushButton = new QPushButton(""); |
||||
|
// 随机分配初始按钮背景色
|
||||
|
static int r = 0, g = 0, b = 0; |
||||
|
r += 150; |
||||
|
g += 50; |
||||
|
b += 100; |
||||
|
if (r > 255) r -= 255; |
||||
|
if (g > 255) g -= 255; |
||||
|
if (b > 255) b -= 255; |
||||
|
QPalette pal; |
||||
|
pal.setColor(QPalette::Button, QColor(r, g, b)); |
||||
|
GraphColorPushButton->setPalette(pal); |
||||
|
GraphColorPushButton->setAutoFillBackground(true); // 该句不能缺少,否则背景颜色无法改变
|
||||
|
GraphColorPushButton->setFlat(true); |
||||
|
// 固定颜色按钮大小
|
||||
|
GraphColorPushButton->setMinimumHeight(18); // 固定高度
|
||||
|
GraphColorPushButton->setMaximumHeight(18); |
||||
|
GraphColorPushButton->setMinimumWidth(30); // 固定宽度
|
||||
|
GraphColorPushButton->setMaximumWidth(30); |
||||
|
connect(GraphColorPushButton, SIGNAL(clicked()), this, SLOT(changeGraphColor())); |
||||
|
ui->treeWidget->setItemWidget(item, 2, GraphColorPushButton); |
||||
|
GraphColorPushButtonVector.append(GraphColorPushButton); |
||||
|
//----------------------------------------------------------------------------------------//
|
||||
|
// 添加曲线
|
||||
|
ui->customPlot->addGraph(); |
||||
|
ui->customPlot->graph(ui->customPlot->graphCount() - 1)->setPen(QPen(QColor(r, g, b))); |
||||
|
ui->customPlot->graph(ui->customPlot->graphCount() - 1)->setVisible(true); |
||||
|
// 将曲线名称与曲线序号一一对应,之后添加数据就可以一一对应
|
||||
|
nameToGraphMap[name.at(i)] = i; |
||||
|
// 初始化数据容器的值
|
||||
|
for (int t = 0; t < name.length(); t++) { |
||||
|
valueVector.append(0); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* 添加数据 */ |
||||
|
void WidgetPlot2D::addData(QString name, double value, int offms) { |
||||
|
// 如果点击了“暂停”按钮,则不绘制图形
|
||||
|
if (ui->pausePBtn->text() == "开始") return; |
||||
|
// 系统当前时间 = 系统运行初始时间 + 系统运行时间
|
||||
|
static double start = time.hour() * 60 * 60 + time.minute() * 60 + time.second() + time.msec() / 1000.0; |
||||
|
double key = start + time.elapsed() / 1000.0 + offms / 1000; |
||||
|
// double start = 0;
|
||||
|
// static int key = 0;
|
||||
|
// key++;
|
||||
|
// qDebug() << "start" << start;
|
||||
|
// qDebug() << "key" << key;
|
||||
|
// 子网格显示
|
||||
|
ui->customPlot->xAxis->grid()->setSubGridVisible(ui->subGridCheck->isChecked()); |
||||
|
ui->customPlot->yAxis->grid()->setSubGridVisible(ui->subGridCheck->isChecked()); |
||||
|
// 自适应量程
|
||||
|
if (ui->autoRangeCheck->isChecked()) { |
||||
|
ui->customPlot->rescaleAxes(); |
||||
|
} |
||||
|
// 设置时间轴
|
||||
|
int timeAxis = ui->timeAxisSpin->value(); |
||||
|
ui->customPlot->xAxis->setRange(key, timeAxis, Qt::AlignRight); |
||||
|
// x轴和y轴全程显示
|
||||
|
if (ui->fullShowCheck->isChecked()) { |
||||
|
ui->customPlot->rescaleAxes(); |
||||
|
} |
||||
|
// 刷新绘图水平滚动条
|
||||
|
ui->horizontalScrollBar->setRange(int(start), int(key)); // 刷新滚动条的范围
|
||||
|
ui->horizontalScrollBar->setPageStep(1); // 设置翻页步长为 1s 的宽度
|
||||
|
ui->horizontalScrollBar->setValue(int(key)); // 调整滑块位置到最右边
|
||||
|
// 更新曲线绘图
|
||||
|
ui->customPlot->graph(nameToGraphMap[name])->addData(key, value); |
||||
|
// ui->customPlot->replot();
|
||||
|
// 使用rpQueuedReplot参数可以加快绘图速度,避免不必要的重复绘制
|
||||
|
ui->customPlot->replot(QCustomPlot::rpQueuedReplot); |
||||
|
// 存储曲线的当前值
|
||||
|
valueVector[nameToGraphMap[name]] = value; |
||||
|
//----------------------------------------------------------------------------------------//
|
||||
|
// 计算每秒的帧率
|
||||
|
static double lastFpsKey = key; |
||||
|
static int frameCount = 0; |
||||
|
frameCount++; |
||||
|
// 每2秒显示一次帧率
|
||||
|
if (key - lastFpsKey > 0.5) { |
||||
|
uint64_t sum = 0; |
||||
|
for (int i = 0; i < ui->customPlot->plottableCount(); i++) { |
||||
|
sum += uint64_t(ui->customPlot->graph(i)->data()->size()); |
||||
|
} |
||||
|
ui->statusLabel->setText(QString("%1 FPS, Total Data points: %2").arg(frameCount / (key - lastFpsKey), 0, 'f', 0).arg(sum)); |
||||
|
lastFpsKey = key; |
||||
|
frameCount = 0; |
||||
|
// 更新数据标签
|
||||
|
for (int t = 0; t < ui->customPlot->plottableCount(); t++) { |
||||
|
valueLabelVector[t]->setText(QString::number(valueVector[t])); |
||||
|
} |
||||
|
} |
||||
|
//----------------------------------------------------------------------------------------//
|
||||
|
} |
||||
|
|
||||
|
/* 曲线是否显示 */ |
||||
|
void WidgetPlot2D::changeGraphVisible() { |
||||
|
for (int i = 0; i < isShowCheckBoxVector.length(); i++) { |
||||
|
ui->customPlot->graph(i)->setVisible(isShowCheckBoxVector[i]->isChecked()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* 改变曲线颜色 */ |
||||
|
void WidgetPlot2D::changeGraphColor() { |
||||
|
/* 在槽(SLOT)中sender()函数会返回一个指向 QObject 的指针来指向信号的发送者。
|
||||
|
* 然后通过 C++ RTTI(Run-Time Type Identification)机制提供的dynamic_cast运算符, |
||||
|
* 在执行的时候检查sender()返回的对象是否是QPushButton类,如果是则将sender()返回的QObject指针转换为QPushButton指针, |
||||
|
* 然后if中的语句就会执行。如果sender()返回的对象不是QPushButton类型的指针,则dynamic_cast就会返回0,if中的语句就不会执行了。 |
||||
|
* */ |
||||
|
if (QPushButton* btn = dynamic_cast<QPushButton*>(sender())) { |
||||
|
QColor color = QColorDialog::getColor(Qt::white, this); |
||||
|
// 用户取消颜色对话框
|
||||
|
if (color.isValid() == false) return; |
||||
|
// 设置按钮背景色
|
||||
|
QPalette pal; // = btn->palette();
|
||||
|
pal.setColor(QPalette::Button, color); |
||||
|
btn->setPalette(pal); |
||||
|
btn->setAutoFillBackground(true); // 该句不能缺少,否则背景颜色无法改变
|
||||
|
btn->setFlat(true); // 该句不能缺少,否则背景颜色无法改变
|
||||
|
} |
||||
|
// 改变对应的曲线颜色
|
||||
|
for (int i = 0; i < GraphColorPushButtonVector.length(); i++) { |
||||
|
// 获取按钮的颜色
|
||||
|
QPalette pal = GraphColorPushButtonVector[i]->palette(); |
||||
|
QColor color = pal.color(QPalette::Button); |
||||
|
// 曲线颜色对应按钮颜色
|
||||
|
ui->customPlot->graph(i)->setPen(QPen(color)); |
||||
|
} |
||||
|
ui->customPlot->replot(); |
||||
|
} |
||||
|
|
||||
|
/* QCP绘图初始化 */ |
||||
|
void WidgetPlot2D::initQCP() { |
||||
|
// 刻度显示
|
||||
|
ui->customPlot->xAxis->setTicks(true); |
||||
|
ui->customPlot->yAxis->setTicks(true); |
||||
|
// 刻度值显示
|
||||
|
ui->customPlot->xAxis->setTickLabels(true); |
||||
|
ui->customPlot->yAxis->setTickLabels(true); |
||||
|
// 网格显示
|
||||
|
ui->customPlot->xAxis->grid()->setVisible(true); |
||||
|
ui->customPlot->yAxis->grid()->setVisible(true); |
||||
|
// 子网格显示
|
||||
|
ui->customPlot->xAxis->grid()->setSubGridVisible(false); |
||||
|
ui->customPlot->yAxis->grid()->setSubGridVisible(false); |
||||
|
// 右和上坐标轴、刻度值显示
|
||||
|
ui->customPlot->xAxis2->setVisible(true); |
||||
|
ui->customPlot->yAxis2->setVisible(true); |
||||
|
ui->customPlot->yAxis2->setTicks(true); |
||||
|
ui->customPlot->yAxis2->setTickLabels(true); |
||||
|
// make top right axes clones of bottom left axes. Looks prettier:
|
||||
|
// ui->customPlot->axisRect()->setupFullAxesBox();
|
||||
|
// make left and bottom axes always transfer their ranges to right and top axes:
|
||||
|
connect(ui->customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), ui->customPlot->xAxis2, SLOT(setRange(QCPRange))); |
||||
|
connect(ui->customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->customPlot->yAxis2, SLOT(setRange(QCPRange))); |
||||
|
// 暗色主题
|
||||
|
// setPlotTheme(Qt::white, Qt::black);
|
||||
|
// 亮色主题
|
||||
|
setTheme(Qt::black, Qt::white); |
||||
|
// 可放大缩小和移动
|
||||
|
ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); |
||||
|
// x轴以时间形式显示
|
||||
|
QSharedPointer<QCPAxisTickerTime> timeTicker(new QCPAxisTickerTime); |
||||
|
timeTicker->setTimeFormat("%h:%m:%s"); |
||||
|
ui->customPlot->xAxis->setTicker(timeTicker); |
||||
|
ui->customPlot->axisRect()->setupFullAxesBox(); |
||||
|
ui->customPlot->replot(); |
||||
|
} |
||||
|
|
||||
|
/* 设置绘图主题 */ |
||||
|
void WidgetPlot2D::setTheme(QColor axis, QColor background) { |
||||
|
// 坐标颜色按钮
|
||||
|
QPalette pal = ui->axisColorPBtn->palette(); |
||||
|
pal.setColor(QPalette::Button, axis); |
||||
|
ui->axisColorPBtn->setPalette(pal); |
||||
|
ui->axisColorPBtn->setAutoFillBackground(true); // 该句不能缺少,否则背景颜色无法改变
|
||||
|
ui->axisColorPBtn->setFlat(true); // 该句不能缺少,否则背景颜色无法改变
|
||||
|
// 背景颜色按钮
|
||||
|
pal = ui->backgroundColorPBtn->palette(); |
||||
|
pal.setColor(QPalette::Button, background); |
||||
|
ui->backgroundColorPBtn->setPalette(pal); |
||||
|
ui->backgroundColorPBtn->setAutoFillBackground(true); // 该句不能缺少,否则背景颜色无法改变
|
||||
|
ui->backgroundColorPBtn->setFlat(true); // 该句不能缺少,否则背景颜色无法改变
|
||||
|
//----------------------------------------------------------------------------------------//
|
||||
|
// 坐标标注颜色
|
||||
|
ui->customPlot->xAxis->setLabelColor(axis); |
||||
|
ui->customPlot->yAxis->setLabelColor(axis); |
||||
|
// 坐标刻度值颜色
|
||||
|
ui->customPlot->xAxis->setTickLabelColor(axis); |
||||
|
ui->customPlot->yAxis->setTickLabelColor(axis); |
||||
|
// 坐标基线颜色和宽度
|
||||
|
ui->customPlot->xAxis->setBasePen(QPen(axis, 1)); |
||||
|
ui->customPlot->yAxis->setBasePen(QPen(axis, 1)); |
||||
|
// 坐标主刻度颜色和宽度
|
||||
|
ui->customPlot->xAxis->setTickPen(QPen(axis, 1)); |
||||
|
ui->customPlot->yAxis->setTickPen(QPen(axis, 1)); |
||||
|
// 坐标子刻度颜色和宽度
|
||||
|
ui->customPlot->xAxis->setSubTickPen(QPen(axis, 1)); |
||||
|
ui->customPlot->yAxis->setSubTickPen(QPen(axis, 1)); |
||||
|
// 坐标标注颜色
|
||||
|
ui->customPlot->xAxis2->setLabelColor(axis); |
||||
|
ui->customPlot->yAxis2->setLabelColor(axis); |
||||
|
// 坐标刻度值颜色
|
||||
|
ui->customPlot->xAxis2->setTickLabelColor(axis); |
||||
|
ui->customPlot->yAxis2->setTickLabelColor(axis); |
||||
|
// 坐标基线颜色和宽度
|
||||
|
ui->customPlot->xAxis2->setBasePen(QPen(axis, 1)); |
||||
|
ui->customPlot->yAxis2->setBasePen(QPen(axis, 1)); |
||||
|
// 坐标主刻度颜色和宽度
|
||||
|
ui->customPlot->xAxis2->setTickPen(QPen(axis, 1)); |
||||
|
ui->customPlot->yAxis2->setTickPen(QPen(axis, 1)); |
||||
|
// 坐标子刻度颜色和宽度
|
||||
|
ui->customPlot->xAxis2->setSubTickPen(QPen(axis, 1)); |
||||
|
ui->customPlot->yAxis2->setSubTickPen(QPen(axis, 1)); |
||||
|
// 整个画布背景色
|
||||
|
ui->customPlot->setBackground(background); |
||||
|
// 绘图区域背景色
|
||||
|
ui->customPlot->axisRect()->setBackground(background); |
||||
|
// 刷新绘图
|
||||
|
ui->customPlot->replot(); |
||||
|
} |
||||
|
|
||||
|
/* 初始化控件 */ |
||||
|
void WidgetPlot2D::initWidget() { |
||||
|
// 时间轴默认时间宽度
|
||||
|
ui->timeAxisSpin->setValue(20); |
||||
|
// 主题
|
||||
|
QStringList theme; |
||||
|
theme << "亮色" |
||||
|
<< "暗色" |
||||
|
<< "自定义"; |
||||
|
ui->themeCombo->addItems(theme); |
||||
|
connect(ui->themeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(changePlotTheme())); |
||||
|
//----------------------------------------------------------------------------------------//
|
||||
|
// 坐标颜色按钮
|
||||
|
QPalette pal = ui->axisColorPBtn->palette(); |
||||
|
pal.setColor(QPalette::Button, Qt::black); |
||||
|
ui->axisColorPBtn->setPalette(pal); |
||||
|
ui->axisColorPBtn->setAutoFillBackground(true); // 该句不能缺少,否则背景颜色无法改变
|
||||
|
ui->axisColorPBtn->setFlat(true); // 该句不能缺少,否则背景颜色无法改变
|
||||
|
connect(ui->axisColorPBtn, SIGNAL(clicked()), this, SLOT(changePlotTheme())); |
||||
|
// 背景颜色按钮
|
||||
|
pal = ui->backgroundColorPBtn->palette(); |
||||
|
pal.setColor(QPalette::Button, Qt::white); |
||||
|
ui->backgroundColorPBtn->setPalette(pal); |
||||
|
ui->backgroundColorPBtn->setAutoFillBackground(true); // 该句不能缺少,否则背景颜色无法改变
|
||||
|
ui->backgroundColorPBtn->setFlat(true); // 该句不能缺少,否则背景颜色无法改变
|
||||
|
connect(ui->backgroundColorPBtn, SIGNAL(clicked()), this, SLOT(changePlotTheme())); |
||||
|
// 操作按钮
|
||||
|
connect(ui->clearPBtn, SIGNAL(clicked()), this, SLOT(plotOperation())); |
||||
|
connect(ui->fullShowPBtn, SIGNAL(clicked()), this, SLOT(plotOperation())); |
||||
|
connect(ui->savePBtn, SIGNAL(clicked()), this, SLOT(plotOperation())); |
||||
|
connect(ui->pausePBtn, SIGNAL(clicked()), this, SLOT(plotOperation())); |
||||
|
//----------------------------------------------------------------------------------------//
|
||||
|
} |
||||
|
|
||||
|
/* 改变画图主题 */ |
||||
|
void WidgetPlot2D::changePlotTheme() { |
||||
|
// 主题选择
|
||||
|
if (QComboBox* combo = dynamic_cast<QComboBox*>(sender())) { |
||||
|
if (combo->currentText() == "亮色") { |
||||
|
setTheme(Qt::black, Qt::white); // 亮色主题
|
||||
|
|
||||
|
} else if (combo->currentText() == "暗色") { |
||||
|
setTheme(Qt::white, Qt::black); // 暗色主题
|
||||
|
|
||||
|
} else if (combo->currentText() == "自定义") { |
||||
|
// 绘图坐标颜色
|
||||
|
QPalette axisPal = ui->axisColorPBtn->palette(); |
||||
|
QColor axisColor = axisPal.color(QPalette::Button); |
||||
|
// 绘图背景颜色
|
||||
|
QPalette backgroundPal = ui->backgroundColorPBtn->palette(); |
||||
|
QColor backgroundColor = backgroundPal.color(QPalette::Button); |
||||
|
|
||||
|
setTheme(axisColor, backgroundColor); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 用户自定义主题
|
||||
|
if (QPushButton* btn = dynamic_cast<QPushButton*>(sender())) { |
||||
|
QColor color = QColorDialog::getColor(Qt::white, this); |
||||
|
// 用户取消颜色对话框
|
||||
|
if (color.isValid() == false) return; |
||||
|
// 设置按钮背景色
|
||||
|
QPalette pal = btn->palette(); |
||||
|
pal.setColor(QPalette::Button, color); |
||||
|
btn->setPalette(pal); |
||||
|
btn->setAutoFillBackground(true); // 该句不能缺少,否则背景颜色无法改变
|
||||
|
btn->setFlat(true); // 该句不能缺少,否则背景颜色无法改变
|
||||
|
// 绘图坐标颜色
|
||||
|
QPalette axisPal = ui->axisColorPBtn->palette(); |
||||
|
QColor axisColor = axisPal.color(QPalette::Button); |
||||
|
// 绘图背景颜色
|
||||
|
QPalette backgroundPal = ui->backgroundColorPBtn->palette(); |
||||
|
QColor backgroundColor = backgroundPal.color(QPalette::Button); |
||||
|
// 改变主题颜色
|
||||
|
setTheme(axisColor, backgroundColor); |
||||
|
ui->themeCombo->setCurrentText("自定义"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* 绘图操作 */ |
||||
|
void WidgetPlot2D::plotOperation() { |
||||
|
if (QPushButton* btn = dynamic_cast<QPushButton*>(sender())) { |
||||
|
if (btn->text() == "清除") { |
||||
|
for (int i = 0; i < ui->customPlot->graphCount(); i++) { |
||||
|
// 先获得每条曲线的数据指针,然后删除数据
|
||||
|
ui->customPlot->graph(i)->data()->clear(); |
||||
|
ui->customPlot->replot(); |
||||
|
time = QTime::currentTime(); |
||||
|
} |
||||
|
} |
||||
|
if (btn->text() == "整图") { |
||||
|
ui->customPlot->rescaleAxes(); |
||||
|
ui->customPlot->replot(); |
||||
|
} |
||||
|
if (btn->text() == "保存") { |
||||
|
savePlotPng(); |
||||
|
} |
||||
|
if (btn->text() == "暂停") { |
||||
|
btn->setText("开始"); |
||||
|
QIcon icon(":/image/player.png"); |
||||
|
btn->setIcon(icon); |
||||
|
} else if (btn->text() == "开始") { |
||||
|
btn->setText("暂停"); |
||||
|
QIcon icon(":/image/pause.png"); |
||||
|
btn->setIcon(icon); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* 判断路径是否存在,不存在则新建,只能创建一级子目录,必须保证上级目录存在 */ |
||||
|
bool WidgetPlot2D::isDirExist(QString fullPath) { |
||||
|
QDir dir(fullPath); |
||||
|
if (dir.exists()) { |
||||
|
return true; |
||||
|
} else { |
||||
|
// 创建一级子目录,必须保证上级目录存在
|
||||
|
bool ok = dir.mkdir(fullPath); |
||||
|
return ok; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* 保存绘图成图片 */ |
||||
|
void WidgetPlot2D::savePlotPng() { |
||||
|
// 获取程序运行路径
|
||||
|
QString savePath = QCoreApplication::applicationDirPath() + "/output"; |
||||
|
// 判断文件路径
|
||||
|
if (isDirExist(savePath)) { |
||||
|
} else { |
||||
|
qDebug() << "保存文件目录未找到!"; |
||||
|
QMessageBox::warning(this, "warning", "保存文件目录未找到!", QMessageBox::Yes, QMessageBox::Yes); |
||||
|
} |
||||
|
QString fileName = QFileDialog::getSaveFileName(this, |
||||
|
"保存波形数据", // 对话框的标题
|
||||
|
savePath, // 保存的默认路径为程序运行路径
|
||||
|
"Save Picture (*.png *jpg)"); // 打开文件的类型,;隔开
|
||||
|
// 如果用户点击了“取消”按钮
|
||||
|
if (fileName.isNull()) return; |
||||
|
// 保存图片
|
||||
|
ui->customPlot->savePng(fileName, 1280, 800, 1.0, -1, 255); |
||||
|
} |
||||
|
|
||||
|
/* 水平滚动条移动 */ |
||||
|
void WidgetPlot2D::horzScrollBarChanged(int value) { |
||||
|
// 若全程显示,则不移动绘图坐标
|
||||
|
if (ui->fullShowCheck->isChecked()) return; |
||||
|
int timeAxis = ui->timeAxisSpin->value(); |
||||
|
ui->customPlot->xAxis->setRange(value, timeAxis, Qt::AlignRight); |
||||
|
ui->customPlot->replot(); |
||||
|
} |
@ -0,0 +1,54 @@ |
|||||
|
#ifndef WIDGETPLOT2D_H |
||||
|
#define WIDGETPLOT2D_H |
||||
|
|
||||
|
#include <QWidget> |
||||
|
#include <QCheckBox> |
||||
|
#include <QLabel> |
||||
|
#include <QPushButton> |
||||
|
#include "qcustomplot.h" |
||||
|
|
||||
|
namespace Ui { |
||||
|
class WidgetPlot2D; |
||||
|
} |
||||
|
|
||||
|
class WidgetPlot2D : public QWidget |
||||
|
{ |
||||
|
Q_OBJECT |
||||
|
|
||||
|
public: |
||||
|
explicit WidgetPlot2D(QWidget *parent = 0); |
||||
|
~WidgetPlot2D(); |
||||
|
|
||||
|
void initGraphName(QStringList name); |
||||
|
|
||||
|
private: |
||||
|
Ui::WidgetPlot2D *ui; |
||||
|
|
||||
|
QVector<QCheckBox*> isShowCheckBoxVector; // 是否显示勾选框 |
||||
|
QVector<QLabel*> valueLabelVector; // label数值显示 |
||||
|
QVector<QPushButton*> GraphColorPushButtonVector; // 曲线颜色选择按钮 |
||||
|
QMap<QString, int> nameToGraphMap; // 曲线名称对应曲线序号 |
||||
|
QVector<double> valueVector; // 存储曲线的当前值 |
||||
|
QTime time; |
||||
|
|
||||
|
int pointNum = 0; |
||||
|
|
||||
|
void initQCP(); |
||||
|
void initWidget(); |
||||
|
void setTheme(QColor axis, QColor background); |
||||
|
bool isDirExist(QString fullPath); |
||||
|
void savePlotPng(); |
||||
|
|
||||
|
|
||||
|
private slots: |
||||
|
void changeGraphVisible(); |
||||
|
void changeGraphColor(); |
||||
|
void plotOperation(); |
||||
|
void horzScrollBarChanged(int value); |
||||
|
void changePlotTheme(); |
||||
|
|
||||
|
public slots: |
||||
|
void addData(QString name, double value,int offms); |
||||
|
}; |
||||
|
|
||||
|
#endif // WIDGETPLOT2D_H |
@ -0,0 +1,351 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<ui version="4.0"> |
||||
|
<class>WidgetPlot2D</class> |
||||
|
<widget class="QWidget" name="WidgetPlot2D"> |
||||
|
<property name="geometry"> |
||||
|
<rect> |
||||
|
<x>0</x> |
||||
|
<y>0</y> |
||||
|
<width>904</width> |
||||
|
<height>531</height> |
||||
|
</rect> |
||||
|
</property> |
||||
|
<property name="windowTitle"> |
||||
|
<string>Form</string> |
||||
|
</property> |
||||
|
<property name="styleSheet"> |
||||
|
<string notr="true">/******************** QGroupBox ***********************/ |
||||
|
QGroupBox#plotUiGroup, #plotShowGroup, #plotOperGroup, #plotSetupGroup |
||||
|
{ |
||||
|
min-width: 150px; |
||||
|
max-width: 150px; |
||||
|
|
||||
|
min-height: 100px; |
||||
|
max-height: 100px; |
||||
|
|
||||
|
border: 1px solid darkGreen; |
||||
|
border-radius: 8px; |
||||
|
background: rgba(250, 240, 230, 0.7); /*背景半透明 */ |
||||
|
margin: 5px 0px 0px 0px; |
||||
|
} |
||||
|
|
||||
|
QGroupBox#plotGroup |
||||
|
{ |
||||
|
border: 1px solid darkGreen; |
||||
|
border-radius: 3px; |
||||
|
margin: 5px 0px 0px 0px; |
||||
|
} |
||||
|
|
||||
|
QGroupBox::title |
||||
|
{ |
||||
|
subcontrol-origin: margin; |
||||
|
subcontrol-position: top; |
||||
|
} |
||||
|
|
||||
|
/****************** QPushButton *******************/ |
||||
|
QPushButton#clearPBtn, #fullShowPBtn, #savePBtn, #openPBtn, #pausePBtn |
||||
|
{ |
||||
|
border: 1px solid black; |
||||
|
background-color: lightGray; |
||||
|
width: 25px; |
||||
|
height: 20px; |
||||
|
border-radius: 5px; /* 边框圆角半径 */ |
||||
|
} |
||||
|
|
||||
|
QPushButton#clearPBtn:hover, #fullShowPBtn:hover, #savePBtn:hover, #openPBtn:hover, #pausePBtn:hover |
||||
|
{ |
||||
|
border: 1px solid darkCyan; |
||||
|
border-radius: 5px; /* 边框圆角半径 */ |
||||
|
} |
||||
|
|
||||
|
QPushButton#clearPBtn:pressed, #fullShowPBtn:pressed, #savePBtn:pressed, #openPBtn:pressed, #pausePBtn:pressed |
||||
|
{ |
||||
|
color: white; |
||||
|
border: 1px solid darkCyan; |
||||
|
background-color: darkCyan; /* 背景 */ |
||||
|
border-radius: 5px; /* 边框圆角半径 */ |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/***********************QScrollBar****************************/ |
||||
|
|
||||
|
|
||||
|
|
||||
|
</string> |
||||
|
</property> |
||||
|
<layout class="QHBoxLayout" name="horizontalLayout"> |
||||
|
<item> |
||||
|
<widget class="QSplitter" name="splitter1"> |
||||
|
<property name="orientation"> |
||||
|
<enum>Qt::Horizontal</enum> |
||||
|
</property> |
||||
|
<widget class="QSplitter" name="splitter"> |
||||
|
<property name="orientation"> |
||||
|
<enum>Qt::Vertical</enum> |
||||
|
</property> |
||||
|
<widget class="QGroupBox" name="plotGroup"> |
||||
|
<property name="sizePolicy"> |
||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding"> |
||||
|
<horstretch>0</horstretch> |
||||
|
<verstretch>0</verstretch> |
||||
|
</sizepolicy> |
||||
|
</property> |
||||
|
<property name="title"> |
||||
|
<string/> |
||||
|
</property> |
||||
|
<layout class="QVBoxLayout" name="verticalLayout_2"> |
||||
|
<property name="spacing"> |
||||
|
<number>1</number> |
||||
|
</property> |
||||
|
<property name="leftMargin"> |
||||
|
<number>1</number> |
||||
|
</property> |
||||
|
<property name="topMargin"> |
||||
|
<number>5</number> |
||||
|
</property> |
||||
|
<property name="rightMargin"> |
||||
|
<number>1</number> |
||||
|
</property> |
||||
|
<property name="bottomMargin"> |
||||
|
<number>1</number> |
||||
|
</property> |
||||
|
<item> |
||||
|
<widget class="QCustomPlot" name="customPlot" native="true"> |
||||
|
<property name="sizePolicy"> |
||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> |
||||
|
<horstretch>0</horstretch> |
||||
|
<verstretch>0</verstretch> |
||||
|
</sizepolicy> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item> |
||||
|
<widget class="QScrollBar" name="horizontalScrollBar"> |
||||
|
<property name="orientation"> |
||||
|
<enum>Qt::Horizontal</enum> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
</layout> |
||||
|
</widget> |
||||
|
<widget class="QWidget" name="layoutWidget"> |
||||
|
<layout class="QVBoxLayout" name="verticalLayout"> |
||||
|
<item> |
||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2"> |
||||
|
<item> |
||||
|
<widget class="QGroupBox" name="plotUiGroup"> |
||||
|
<property name="title"> |
||||
|
<string>颜色</string> |
||||
|
</property> |
||||
|
<property name="alignment"> |
||||
|
<set>Qt::AlignCenter</set> |
||||
|
</property> |
||||
|
<layout class="QGridLayout" name="gridLayout"> |
||||
|
<item row="0" column="1"> |
||||
|
<widget class="QComboBox" name="themeCombo"/> |
||||
|
</item> |
||||
|
<item row="1" column="0"> |
||||
|
<widget class="QLabel" name="label_2"> |
||||
|
<property name="text"> |
||||
|
<string>坐标颜色</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="0" column="0"> |
||||
|
<widget class="QLabel" name="label"> |
||||
|
<property name="text"> |
||||
|
<string>主题</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="2" column="0"> |
||||
|
<widget class="QLabel" name="label_3"> |
||||
|
<property name="text"> |
||||
|
<string>背景颜色</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="2" column="1"> |
||||
|
<widget class="QPushButton" name="backgroundColorPBtn"> |
||||
|
<property name="text"> |
||||
|
<string/> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="1" column="1"> |
||||
|
<widget class="QPushButton" name="axisColorPBtn"> |
||||
|
<property name="text"> |
||||
|
<string/> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
</layout> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item> |
||||
|
<widget class="QGroupBox" name="plotShowGroup"> |
||||
|
<property name="title"> |
||||
|
<string>显示</string> |
||||
|
</property> |
||||
|
<property name="alignment"> |
||||
|
<set>Qt::AlignCenter</set> |
||||
|
</property> |
||||
|
<layout class="QGridLayout" name="gridLayout_2"> |
||||
|
<item row="0" column="0" colspan="2"> |
||||
|
<widget class="QCheckBox" name="autoRangeCheck"> |
||||
|
<property name="text"> |
||||
|
<string>自适应量程</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="1" column="0" colspan="2"> |
||||
|
<widget class="QCheckBox" name="subGridCheck"> |
||||
|
<property name="text"> |
||||
|
<string>显示子网格</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="2" column="0"> |
||||
|
<widget class="QLabel" name="label_4"> |
||||
|
<property name="text"> |
||||
|
<string>时间轴:</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="2" column="1" colspan="2"> |
||||
|
<widget class="QSpinBox" name="timeAxisSpin"> |
||||
|
<property name="suffix"> |
||||
|
<string> s</string> |
||||
|
</property> |
||||
|
<property name="prefix"> |
||||
|
<string/> |
||||
|
</property> |
||||
|
<property name="minimum"> |
||||
|
<number>1</number> |
||||
|
</property> |
||||
|
<property name="maximum"> |
||||
|
<number>999999999</number> |
||||
|
</property> |
||||
|
<property name="value"> |
||||
|
<number>10</number> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="0" column="2"> |
||||
|
<widget class="QCheckBox" name="fullShowCheck"> |
||||
|
<property name="text"> |
||||
|
<string>全程</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
</layout> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item> |
||||
|
<widget class="QGroupBox" name="plotOperGroup"> |
||||
|
<property name="minimumSize"> |
||||
|
<size> |
||||
|
<width>152</width> |
||||
|
<height>107</height> |
||||
|
</size> |
||||
|
</property> |
||||
|
<property name="title"> |
||||
|
<string>操作</string> |
||||
|
</property> |
||||
|
<property name="alignment"> |
||||
|
<set>Qt::AlignCenter</set> |
||||
|
</property> |
||||
|
<layout class="QGridLayout" name="gridLayout_3"> |
||||
|
<item row="0" column="2"> |
||||
|
<widget class="QPushButton" name="fullShowPBtn"> |
||||
|
<property name="text"> |
||||
|
<string>整图</string> |
||||
|
</property> |
||||
|
<property name="checkable"> |
||||
|
<bool>false</bool> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="0" column="0"> |
||||
|
<widget class="QPushButton" name="clearPBtn"> |
||||
|
<property name="text"> |
||||
|
<string>清除</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="1" column="0"> |
||||
|
<widget class="QPushButton" name="savePBtn"> |
||||
|
<property name="text"> |
||||
|
<string>保存</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="1" column="2"> |
||||
|
<widget class="QPushButton" name="pausePBtn"> |
||||
|
<property name="text"> |
||||
|
<string>暂停</string> |
||||
|
</property> |
||||
|
<property name="icon"> |
||||
|
<iconset resource="image.qrc"> |
||||
|
<normaloff>:/image/pause.png</normaloff>:/image/pause.png</iconset> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
</layout> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item> |
||||
|
<spacer name="horizontalSpacer"> |
||||
|
<property name="orientation"> |
||||
|
<enum>Qt::Horizontal</enum> |
||||
|
</property> |
||||
|
<property name="sizeHint" stdset="0"> |
||||
|
<size> |
||||
|
<width>40</width> |
||||
|
<height>20</height> |
||||
|
</size> |
||||
|
</property> |
||||
|
</spacer> |
||||
|
</item> |
||||
|
</layout> |
||||
|
</item> |
||||
|
<item> |
||||
|
<widget class="QLabel" name="statusLabel"> |
||||
|
<property name="sizePolicy"> |
||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> |
||||
|
<horstretch>0</horstretch> |
||||
|
<verstretch>0</verstretch> |
||||
|
</sizepolicy> |
||||
|
</property> |
||||
|
<property name="text"> |
||||
|
<string>绘图状态</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
</layout> |
||||
|
</widget> |
||||
|
</widget> |
||||
|
<widget class="QTreeWidget" name="treeWidget"> |
||||
|
<column> |
||||
|
<property name="text"> |
||||
|
<string notr="true">1</string> |
||||
|
</property> |
||||
|
</column> |
||||
|
</widget> |
||||
|
</widget> |
||||
|
</item> |
||||
|
</layout> |
||||
|
</widget> |
||||
|
<customwidgets> |
||||
|
<customwidget> |
||||
|
<class>QCustomPlot</class> |
||||
|
<extends>QWidget</extends> |
||||
|
<header>qcustomplot.h</header> |
||||
|
<container>1</container> |
||||
|
</customwidget> |
||||
|
</customwidgets> |
||||
|
<resources> |
||||
|
<include location="image.qrc"/> |
||||
|
</resources> |
||||
|
<connections/> |
||||
|
</ui> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue