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