#include "frmplot.h" #include "ui_frmplot.h" #include "quihelper.h" #include "selectwidget.h" #include "frmplotbtn.h" #include "frmplotrect.h" #define DotColor QColor(14, 153, 160) #define LineColor QColor(34, 163, 169) #define TextWidth 0.3 #define LineWidth 1.5 frmPlot::frmPlot(QWidget *parent) : QWidget(parent), ui(new Ui::frmPlot) { ui->setupUi(this); this->initForm(); this->initPlot(); this->initData(); this->loadData(); } frmPlot::~frmPlot() { delete ui; } void frmPlot::showEvent(QShowEvent *) { //X轴单位标签移到右下角 labXUnit->move(customPlot->width() - 40, customPlot->height() - 50); //Y轴单位标签移到左上角 labYUnit->move(40, 5); //当前值标签移到右上角 labValue->move(customPlot->width() - 170, 5); } bool frmPlot::eventFilter(QObject *watched, QEvent *event) { if (watched == customPlot) { QMouseEvent *mouseEvent = static_cast(event); if (mouseEvent->type() == QEvent::MouseMove) { } else if (mouseEvent->type() == QEvent::MouseButtonPress) { //清除所有选中图形 clearFocus(); //如果处于放大模式则单击放大 if (modeMax) { #if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) QWheelEvent wheelEvent(mouseEvent->pos(), scal, Qt::LeftButton, Qt::NoModifier); QApplication::sendEvent(customPlot, &wheelEvent); #endif } //如果处于缩小模式则单击缩小 if (modeMin) { #if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) QWheelEvent wheelEvent(mouseEvent->pos(), -scal, Qt::LeftButton, Qt::NoModifier); QApplication::sendEvent(customPlot, &wheelEvent); #endif } } } return QWidget::eventFilter(watched, event); } void frmPlot::initForm() { //重置所有模式 resetMode(); //X轴数据个数 maxX = 20; //Y轴最大值 maxY = 200; //放大缩小倍数 scal = 20; xUnit = "mm"; yUnit = "N"; value = "97.856 mm / 1188 N"; customPlot = new QCustomPlot; ui->layout->addWidget(customPlot); //实例化模拟数据定时器 timer = new QTimer(this); timer->setInterval(500); connect(timer, SIGNAL(timeout()), this, SLOT(loadData())); //设置按钮悬浮窗体 frmPlotBtn *plotBtn = new frmPlotBtn(customPlot); connect(plotBtn, SIGNAL(btnClicked(int, int)), this, SLOT(btnClicked(int, int))); plotBtn->move(40, 10); //设置XY轴单位 labXUnit = new QLabel(customPlot); labXUnit->setAlignment(Qt::AlignVCenter | Qt::AlignRight); labXUnit->setText(xUnit); labYUnit = new QLabel(customPlot); labYUnit->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); labYUnit->setText(yUnit); labValue = new QLabel(customPlot); labValue->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter); labValue->setText(value); } void frmPlot::initPlot() { //添加画布,每个图表必须至少有一个画布 customPlot->addGraph(); customPlot->graph(0)->setPen(QPen(LineColor, LineWidth)); customPlot->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, QPen(DotColor, LineWidth), QBrush(DotColor), AppConfig::DotWidth)); QFont font = QFont(qApp->font().family(), 8); customPlot->legend->setFont(font); customPlot->xAxis->setLabelFont(font); customPlot->yAxis->setLabelFont(font); customPlot->xAxis->setTickLabelFont(font); customPlot->yAxis->setTickLabelFont(font); //将对应的key用文本替代表示 #ifdef qcustomplot_v1 customPlot->xAxis->setTickVector(keys); customPlot->xAxis->setTickVectorLabels(labs); customPlot->yAxis->setAutoTickCount(7); #else //设置标尺为文本标尺 QSharedPointer ticker(new QCPAxisTickerText); ticker->addTicks(keys, labs); customPlot->xAxis->setTicker(ticker); customPlot->yAxis->ticker()->setTickCount(7); #endif customPlot->yAxis->setRange(0, maxY); //设置图标可以缩放 customPlot->setInteractions(QCP::iRangeZoom | QCP::iSelectOther); customPlot->replot(); //绑定事件过滤器鼠标识别数据点 customPlot->installEventFilter(this); //启动定时器模拟数据 timer->start(); } void frmPlot::initData() { keys.clear(); values.clear(); labs.clear(); for (int i = 0; i < maxX; i++) { keys.append(i); values.append((rand() % 10) + 80); labs.append(QString::number(i + 1)); } } void frmPlot::loadData() { double data = (rand() % 10) + 80; appendData(data); } void frmPlot::resetMode() { modeMax = false; modeMin = false; modeMove = false; } void frmPlot::btnClicked(int parentIndex, int childIndex) { //qDebug() << parentIndex << childIndex; if (parentIndex == 0) { resetMode(); if (childIndex == 1) { setMaxX(maxX); setMaxY(maxY); } else if (childIndex == 2) { customPlot->rescaleAxes(); } else if (childIndex == 3) { modeMax = true; } else if (childIndex == 4) { modeMin = true; } else if (childIndex == 5) { modeMove = true; } else if (childIndex == 6) { } //处于平移模式则设置可以拖动和缩放 if (modeMove) { customPlot->setInteractions(QCP::iRangeZoom | QCP::iRangeDrag); } else { customPlot->setInteractions(QCP::iRangeZoom | QCP::iSelectOther); } } else if (parentIndex == 1) { } else if (parentIndex == 2) { if (childIndex == 1) { frmPlotRect *plotRect = new frmPlotRect(customPlot); plotRect->setGeometry(220, 130, 100, 20); plotRect->setType(0); SelectWidget *selectWidget = new SelectWidget(customPlot); connect(selectWidget, SIGNAL(widgetPressed(QWidget *)), this, SLOT(widgetPressed(QWidget *))); selectWidget->setWidget(plotRect); selectWidgets.append(selectWidget); selectWidget->setFocus(); } else if (childIndex == 2) { frmPlotRect *plotRect = new frmPlotRect(customPlot); plotRect->setGeometry(350, 110, 100, 50); plotRect->setType(1); SelectWidget *selectWidget = new SelectWidget(customPlot); connect(selectWidget, SIGNAL(widgetPressed(QWidget *)), this, SLOT(widgetPressed(QWidget *))); selectWidget->setWidget(plotRect); selectWidgets.append(selectWidget); } } } void frmPlot::clearFocus() { //将原有焦点窗体全部设置成无焦点 foreach (SelectWidget *widget, selectWidgets) { widget->setDrawPoint(false); } } void frmPlot::widgetPressed(QWidget *widget) { clearFocus(); //设置当前按下的控件有焦点 foreach (SelectWidget *w, selectWidgets) { if (w->getWidget() == widget) { w->setDrawPoint(true); break; } } } void frmPlot::setMaxX(int maxX) { this->maxX = maxX; customPlot->xAxis->setRange(-0.5, maxX - 0.5); customPlot->replot(); } void frmPlot::setMaxY(int maxY) { if ((maxY / 20) > 0) { this->maxY = maxY; customPlot->yAxis->setRange(0, maxY); #ifdef qcustomplot_v1 customPlot->yAxis->setAutoTickCount(maxY / 20); #else customPlot->yAxis->ticker()->setTickCount(maxY / 20); #endif customPlot->replot(); } } void frmPlot::appendData(double data) { //移除第一个数据,增加一个数据,保证每次集合数据一致 values.remove(0, 1); values.append(data); customPlot->graph(0)->setData(keys, values); #ifdef qcustomplot_v1 customPlot->xAxis->setTickVector(keys); customPlot->xAxis->setTickVectorLabels(labs); #else QSharedPointer ticker(new QCPAxisTickerText); ticker->addTicks(keys, labs); customPlot->xAxis->setTicker(ticker); #endif customPlot->replot(); } void frmPlot::setXUnit(const QString &xUnit) { this->xUnit = xUnit; labXUnit->setText(xUnit); } void frmPlot::setYUnit(const QString &yUnit) { this->yUnit = yUnit; labYUnit->setText(yUnit); } void frmPlot::setValue(const QString &value) { this->value = value; labValue->setText(value); } void frmPlot::setValue(double x, double y) { value = QString("%1 %2 / %3 %4").arg(x).arg(xUnit).arg(y).arg(yUnit); setValue(value); } void frmPlot::saveData(const QString &fileName) { //保存数据文件 QFile file(fileName + ".csv"); if (file.open(QFile::WriteOnly)) { QStringList data; foreach (double value, values) { data << QString::number(value); } file.write(data.join(",").toLatin1()); } //保存图片文件 customPlot->saveJpg(fileName + ".jpg"); }