diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/PhaseWindow.h b/PhaseWindow.h index bfb44b6..6fc532c 100644 --- a/PhaseWindow.h +++ b/PhaseWindow.h @@ -25,13 +25,14 @@ void drawPhaseDataOnPage(PhaseDataDto * phaseData); private slots: - void on_minButt_clicked(); - void on_exitButt_clicked(); - void on_startButt_clicked(); void on_endButt_clicked(); void on_settingButt_clicked(); + void buttonClick(); + void on_btnMenuMin_clicked(); + void on_btnMenuClose_clicked(); + private: Ui::PhaseWindow *ui; QList channelGroupList; @@ -39,10 +40,12 @@ PhaseDevice * device; - + void initForm(); + void initDeivce(); void createFolder(); void generateWidgetForDevice(); void updateChannelActive(QList channelActive); + void swiftConntrollerButt(); }; #endif // PHASEWINDOW_H diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/PhaseWindow.h b/PhaseWindow.h index bfb44b6..6fc532c 100644 --- a/PhaseWindow.h +++ b/PhaseWindow.h @@ -25,13 +25,14 @@ void drawPhaseDataOnPage(PhaseDataDto * phaseData); private slots: - void on_minButt_clicked(); - void on_exitButt_clicked(); - void on_startButt_clicked(); void on_endButt_clicked(); void on_settingButt_clicked(); + void buttonClick(); + void on_btnMenuMin_clicked(); + void on_btnMenuClose_clicked(); + private: Ui::PhaseWindow *ui; QList channelGroupList; @@ -39,10 +40,12 @@ PhaseDevice * device; - + void initForm(); + void initDeivce(); void createFolder(); void generateWidgetForDevice(); void updateChannelActive(QList channelActive); + void swiftConntrollerButt(); }; #endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui index d25b82b..66d8d47 100644 --- a/PhaseWindow.ui +++ b/PhaseWindow.ui @@ -6,840 +6,1018 @@ 0 0 - 1366 + 1200 720 - 1366 + 1200 0 比相仪测量软件 - - - - 0 - 100 - 100 - 30 - + + + 0 - - - 微软雅黑 - 10 - + + 1 - - QFrame::NoFrame + + 1 - - Qt::ScrollBarAlwaysOff + + 1 - - true + + 1 - - - - 0 - 0 - 100 - 30 - - - - - - - - 1300 - 10 - 40 - 40 - - - - - - - 退出 - - - - - - 0 - 0 - 200 - 50 - - - - - 微软雅黑 - 16 - - - - 比相仪测量软件 - - - Qt::AlignCenter - - - - - - 0 - 90 - 1371 - 16 - - - - QFrame::Plain - - - Qt::Horizontal - - - - - - 1250 - 10 - 40 - 40 - - - - - - - 最小化 - - - - - - 1200 - 10 - 40 - 40 - - - - - - - 配置 - - - - - - 0 - 50 - 240 - 40 - - - - - 微软雅黑 - 12 - 75 - true - - - - Qt::RightToLeft - - - 2021-12-10 10:00:00 - - - Qt::AlignCenter - - - - - - 230 - 35 - 941 - 40 - - - - - 1 - - - - - + + + + + 0 + 0 + + + + + 5 - - :/points/images/green.png + + 20 - - Qt::AlignCenter + + 0 + + + 0 + + + 0 + + + + + + + + Qt::AlignCenter + + + + + + + 0 + + + 10 + + + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + + + + 0 + + + 40 + + + + + + 705 + 0 + + + + + 780 + 30 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + 705 + 0 + + + + + 780 + 40 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 开始测量 + + + + :/images/start.png:/images/start.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 停止测量 + + + + :/images/stop.png:/images/stop.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 系统设置 + + + + :/images/config.png:/images/config.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + 0 + + + 0 + + + 10 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 关闭 + + + + + + + + + + Qt::Vertical + + + + 60 + 37 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 最小化 + + + + + + + + + + + + + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 1198 + 651 + - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - 230 - 65 - 941 - 30 - - - - - 0 - - - 0 - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 1 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 2 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 3 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 4 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 5 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 6 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 7 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 8 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 9 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 10 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 11 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 12 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 13 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 14 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 15 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 16 - - - Qt::AlignCenter - - - - - - - - - 1100 - 10 - 40 - 40 - - - - - - - 开始 - - - - - - 1150 - 10 - 40 - 40 - - - - - - - 结束 - - + + + diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/PhaseWindow.h b/PhaseWindow.h index bfb44b6..6fc532c 100644 --- a/PhaseWindow.h +++ b/PhaseWindow.h @@ -25,13 +25,14 @@ void drawPhaseDataOnPage(PhaseDataDto * phaseData); private slots: - void on_minButt_clicked(); - void on_exitButt_clicked(); - void on_startButt_clicked(); void on_endButt_clicked(); void on_settingButt_clicked(); + void buttonClick(); + void on_btnMenuMin_clicked(); + void on_btnMenuClose_clicked(); + private: Ui::PhaseWindow *ui; QList channelGroupList; @@ -39,10 +40,12 @@ PhaseDevice * device; - + void initForm(); + void initDeivce(); void createFolder(); void generateWidgetForDevice(); void updateChannelActive(QList channelActive); + void swiftConntrollerButt(); }; #endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui index d25b82b..66d8d47 100644 --- a/PhaseWindow.ui +++ b/PhaseWindow.ui @@ -6,840 +6,1018 @@ 0 0 - 1366 + 1200 720 - 1366 + 1200 0 比相仪测量软件 - - - - 0 - 100 - 100 - 30 - + + + 0 - - - 微软雅黑 - 10 - + + 1 - - QFrame::NoFrame + + 1 - - Qt::ScrollBarAlwaysOff + + 1 - - true + + 1 - - - - 0 - 0 - 100 - 30 - - - - - - - - 1300 - 10 - 40 - 40 - - - - - - - 退出 - - - - - - 0 - 0 - 200 - 50 - - - - - 微软雅黑 - 16 - - - - 比相仪测量软件 - - - Qt::AlignCenter - - - - - - 0 - 90 - 1371 - 16 - - - - QFrame::Plain - - - Qt::Horizontal - - - - - - 1250 - 10 - 40 - 40 - - - - - - - 最小化 - - - - - - 1200 - 10 - 40 - 40 - - - - - - - 配置 - - - - - - 0 - 50 - 240 - 40 - - - - - 微软雅黑 - 12 - 75 - true - - - - Qt::RightToLeft - - - 2021-12-10 10:00:00 - - - Qt::AlignCenter - - - - - - 230 - 35 - 941 - 40 - - - - - 1 - - - - - + + + + + 0 + 0 + + + + + 5 - - :/points/images/green.png + + 20 - - Qt::AlignCenter + + 0 + + + 0 + + + 0 + + + + + + + + Qt::AlignCenter + + + + + + + 0 + + + 10 + + + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + + + + 0 + + + 40 + + + + + + 705 + 0 + + + + + 780 + 30 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + 705 + 0 + + + + + 780 + 40 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 开始测量 + + + + :/images/start.png:/images/start.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 停止测量 + + + + :/images/stop.png:/images/stop.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 系统设置 + + + + :/images/config.png:/images/config.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + 0 + + + 0 + + + 10 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 关闭 + + + + + + + + + + Qt::Vertical + + + + 60 + 37 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 最小化 + + + + + + + + + + + + + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 1198 + 651 + - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - 230 - 65 - 941 - 30 - - - - - 0 - - - 0 - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 1 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 2 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 3 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 4 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 5 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 6 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 7 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 8 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 9 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 10 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 11 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 12 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 13 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 14 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 15 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 16 - - - Qt::AlignCenter - - - - - - - - - 1100 - 10 - 40 - 40 - - - - - - - 开始 - - - - - - 1150 - 10 - 40 - 40 - - - - - - - 结束 - - + + + diff --git a/images.qrc b/images.qrc index 0fc1f3e..08fb3f8 100644 --- a/images.qrc +++ b/images.qrc @@ -3,4 +3,18 @@ images/white.png images/green.png + + images/fontawesome-webfont.ttf + images/main_config.png + images/phaseMeasure.png + images/config.png + images/start.png + images/stop.png + images/chart.png + images/clear.png + + + images/add_bottom.png + images/add_top.png + diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/PhaseWindow.h b/PhaseWindow.h index bfb44b6..6fc532c 100644 --- a/PhaseWindow.h +++ b/PhaseWindow.h @@ -25,13 +25,14 @@ void drawPhaseDataOnPage(PhaseDataDto * phaseData); private slots: - void on_minButt_clicked(); - void on_exitButt_clicked(); - void on_startButt_clicked(); void on_endButt_clicked(); void on_settingButt_clicked(); + void buttonClick(); + void on_btnMenuMin_clicked(); + void on_btnMenuClose_clicked(); + private: Ui::PhaseWindow *ui; QList channelGroupList; @@ -39,10 +40,12 @@ PhaseDevice * device; - + void initForm(); + void initDeivce(); void createFolder(); void generateWidgetForDevice(); void updateChannelActive(QList channelActive); + void swiftConntrollerButt(); }; #endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui index d25b82b..66d8d47 100644 --- a/PhaseWindow.ui +++ b/PhaseWindow.ui @@ -6,840 +6,1018 @@ 0 0 - 1366 + 1200 720 - 1366 + 1200 0 比相仪测量软件 - - - - 0 - 100 - 100 - 30 - + + + 0 - - - 微软雅黑 - 10 - + + 1 - - QFrame::NoFrame + + 1 - - Qt::ScrollBarAlwaysOff + + 1 - - true + + 1 - - - - 0 - 0 - 100 - 30 - - - - - - - - 1300 - 10 - 40 - 40 - - - - - - - 退出 - - - - - - 0 - 0 - 200 - 50 - - - - - 微软雅黑 - 16 - - - - 比相仪测量软件 - - - Qt::AlignCenter - - - - - - 0 - 90 - 1371 - 16 - - - - QFrame::Plain - - - Qt::Horizontal - - - - - - 1250 - 10 - 40 - 40 - - - - - - - 最小化 - - - - - - 1200 - 10 - 40 - 40 - - - - - - - 配置 - - - - - - 0 - 50 - 240 - 40 - - - - - 微软雅黑 - 12 - 75 - true - - - - Qt::RightToLeft - - - 2021-12-10 10:00:00 - - - Qt::AlignCenter - - - - - - 230 - 35 - 941 - 40 - - - - - 1 - - - - - + + + + + 0 + 0 + + + + + 5 - - :/points/images/green.png + + 20 - - Qt::AlignCenter + + 0 + + + 0 + + + 0 + + + + + + + + Qt::AlignCenter + + + + + + + 0 + + + 10 + + + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + + + + 0 + + + 40 + + + + + + 705 + 0 + + + + + 780 + 30 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + 705 + 0 + + + + + 780 + 40 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 开始测量 + + + + :/images/start.png:/images/start.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 停止测量 + + + + :/images/stop.png:/images/stop.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 系统设置 + + + + :/images/config.png:/images/config.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + 0 + + + 0 + + + 10 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 关闭 + + + + + + + + + + Qt::Vertical + + + + 60 + 37 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 最小化 + + + + + + + + + + + + + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 1198 + 651 + - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - 230 - 65 - 941 - 30 - - - - - 0 - - - 0 - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 1 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 2 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 3 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 4 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 5 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 6 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 7 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 8 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 9 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 10 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 11 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 12 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 13 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 14 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 15 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 16 - - - Qt::AlignCenter - - - - - - - - - 1100 - 10 - 40 - 40 - - - - - - - 开始 - - - - - - 1150 - 10 - 40 - 40 - - - - - - - 结束 - - + + + diff --git a/images.qrc b/images.qrc index 0fc1f3e..08fb3f8 100644 --- a/images.qrc +++ b/images.qrc @@ -3,4 +3,18 @@ images/white.png images/green.png + + images/fontawesome-webfont.ttf + images/main_config.png + images/phaseMeasure.png + images/config.png + images/start.png + images/stop.png + images/chart.png + images/clear.png + + + images/add_bottom.png + images/add_top.png + diff --git a/images/add_bottom.png b/images/add_bottom.png new file mode 100644 index 0000000..2f8c0f2 --- /dev/null +++ b/images/add_bottom.png Binary files differ diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/PhaseWindow.h b/PhaseWindow.h index bfb44b6..6fc532c 100644 --- a/PhaseWindow.h +++ b/PhaseWindow.h @@ -25,13 +25,14 @@ void drawPhaseDataOnPage(PhaseDataDto * phaseData); private slots: - void on_minButt_clicked(); - void on_exitButt_clicked(); - void on_startButt_clicked(); void on_endButt_clicked(); void on_settingButt_clicked(); + void buttonClick(); + void on_btnMenuMin_clicked(); + void on_btnMenuClose_clicked(); + private: Ui::PhaseWindow *ui; QList channelGroupList; @@ -39,10 +40,12 @@ PhaseDevice * device; - + void initForm(); + void initDeivce(); void createFolder(); void generateWidgetForDevice(); void updateChannelActive(QList channelActive); + void swiftConntrollerButt(); }; #endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui index d25b82b..66d8d47 100644 --- a/PhaseWindow.ui +++ b/PhaseWindow.ui @@ -6,840 +6,1018 @@ 0 0 - 1366 + 1200 720 - 1366 + 1200 0 比相仪测量软件 - - - - 0 - 100 - 100 - 30 - + + + 0 - - - 微软雅黑 - 10 - + + 1 - - QFrame::NoFrame + + 1 - - Qt::ScrollBarAlwaysOff + + 1 - - true + + 1 - - - - 0 - 0 - 100 - 30 - - - - - - - - 1300 - 10 - 40 - 40 - - - - - - - 退出 - - - - - - 0 - 0 - 200 - 50 - - - - - 微软雅黑 - 16 - - - - 比相仪测量软件 - - - Qt::AlignCenter - - - - - - 0 - 90 - 1371 - 16 - - - - QFrame::Plain - - - Qt::Horizontal - - - - - - 1250 - 10 - 40 - 40 - - - - - - - 最小化 - - - - - - 1200 - 10 - 40 - 40 - - - - - - - 配置 - - - - - - 0 - 50 - 240 - 40 - - - - - 微软雅黑 - 12 - 75 - true - - - - Qt::RightToLeft - - - 2021-12-10 10:00:00 - - - Qt::AlignCenter - - - - - - 230 - 35 - 941 - 40 - - - - - 1 - - - - - + + + + + 0 + 0 + + + + + 5 - - :/points/images/green.png + + 20 - - Qt::AlignCenter + + 0 + + + 0 + + + 0 + + + + + + + + Qt::AlignCenter + + + + + + + 0 + + + 10 + + + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + + + + 0 + + + 40 + + + + + + 705 + 0 + + + + + 780 + 30 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + 705 + 0 + + + + + 780 + 40 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 开始测量 + + + + :/images/start.png:/images/start.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 停止测量 + + + + :/images/stop.png:/images/stop.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 系统设置 + + + + :/images/config.png:/images/config.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + 0 + + + 0 + + + 10 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 关闭 + + + + + + + + + + Qt::Vertical + + + + 60 + 37 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 最小化 + + + + + + + + + + + + + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 1198 + 651 + - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - 230 - 65 - 941 - 30 - - - - - 0 - - - 0 - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 1 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 2 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 3 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 4 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 5 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 6 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 7 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 8 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 9 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 10 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 11 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 12 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 13 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 14 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 15 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 16 - - - Qt::AlignCenter - - - - - - - - - 1100 - 10 - 40 - 40 - - - - - - - 开始 - - - - - - 1150 - 10 - 40 - 40 - - - - - - - 结束 - - + + + diff --git a/images.qrc b/images.qrc index 0fc1f3e..08fb3f8 100644 --- a/images.qrc +++ b/images.qrc @@ -3,4 +3,18 @@ images/white.png images/green.png + + images/fontawesome-webfont.ttf + images/main_config.png + images/phaseMeasure.png + images/config.png + images/start.png + images/stop.png + images/chart.png + images/clear.png + + + images/add_bottom.png + images/add_top.png + diff --git a/images/add_bottom.png b/images/add_bottom.png new file mode 100644 index 0000000..2f8c0f2 --- /dev/null +++ b/images/add_bottom.png Binary files differ diff --git a/images/add_top.png b/images/add_top.png new file mode 100644 index 0000000..a5ceb4f --- /dev/null +++ b/images/add_top.png Binary files differ diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/PhaseWindow.h b/PhaseWindow.h index bfb44b6..6fc532c 100644 --- a/PhaseWindow.h +++ b/PhaseWindow.h @@ -25,13 +25,14 @@ void drawPhaseDataOnPage(PhaseDataDto * phaseData); private slots: - void on_minButt_clicked(); - void on_exitButt_clicked(); - void on_startButt_clicked(); void on_endButt_clicked(); void on_settingButt_clicked(); + void buttonClick(); + void on_btnMenuMin_clicked(); + void on_btnMenuClose_clicked(); + private: Ui::PhaseWindow *ui; QList channelGroupList; @@ -39,10 +40,12 @@ PhaseDevice * device; - + void initForm(); + void initDeivce(); void createFolder(); void generateWidgetForDevice(); void updateChannelActive(QList channelActive); + void swiftConntrollerButt(); }; #endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui index d25b82b..66d8d47 100644 --- a/PhaseWindow.ui +++ b/PhaseWindow.ui @@ -6,840 +6,1018 @@ 0 0 - 1366 + 1200 720 - 1366 + 1200 0 比相仪测量软件 - - - - 0 - 100 - 100 - 30 - + + + 0 - - - 微软雅黑 - 10 - + + 1 - - QFrame::NoFrame + + 1 - - Qt::ScrollBarAlwaysOff + + 1 - - true + + 1 - - - - 0 - 0 - 100 - 30 - - - - - - - - 1300 - 10 - 40 - 40 - - - - - - - 退出 - - - - - - 0 - 0 - 200 - 50 - - - - - 微软雅黑 - 16 - - - - 比相仪测量软件 - - - Qt::AlignCenter - - - - - - 0 - 90 - 1371 - 16 - - - - QFrame::Plain - - - Qt::Horizontal - - - - - - 1250 - 10 - 40 - 40 - - - - - - - 最小化 - - - - - - 1200 - 10 - 40 - 40 - - - - - - - 配置 - - - - - - 0 - 50 - 240 - 40 - - - - - 微软雅黑 - 12 - 75 - true - - - - Qt::RightToLeft - - - 2021-12-10 10:00:00 - - - Qt::AlignCenter - - - - - - 230 - 35 - 941 - 40 - - - - - 1 - - - - - + + + + + 0 + 0 + + + + + 5 - - :/points/images/green.png + + 20 - - Qt::AlignCenter + + 0 + + + 0 + + + 0 + + + + + + + + Qt::AlignCenter + + + + + + + 0 + + + 10 + + + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + + + + 0 + + + 40 + + + + + + 705 + 0 + + + + + 780 + 30 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + 705 + 0 + + + + + 780 + 40 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 开始测量 + + + + :/images/start.png:/images/start.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 停止测量 + + + + :/images/stop.png:/images/stop.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 系统设置 + + + + :/images/config.png:/images/config.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + 0 + + + 0 + + + 10 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 关闭 + + + + + + + + + + Qt::Vertical + + + + 60 + 37 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 最小化 + + + + + + + + + + + + + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 1198 + 651 + - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - 230 - 65 - 941 - 30 - - - - - 0 - - - 0 - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 1 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 2 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 3 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 4 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 5 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 6 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 7 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 8 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 9 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 10 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 11 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 12 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 13 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 14 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 15 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 16 - - - Qt::AlignCenter - - - - - - - - - 1100 - 10 - 40 - 40 - - - - - - - 开始 - - - - - - 1150 - 10 - 40 - 40 - - - - - - - 结束 - - + + + diff --git a/images.qrc b/images.qrc index 0fc1f3e..08fb3f8 100644 --- a/images.qrc +++ b/images.qrc @@ -3,4 +3,18 @@ images/white.png images/green.png + + images/fontawesome-webfont.ttf + images/main_config.png + images/phaseMeasure.png + images/config.png + images/start.png + images/stop.png + images/chart.png + images/clear.png + + + images/add_bottom.png + images/add_top.png + diff --git a/images/add_bottom.png b/images/add_bottom.png new file mode 100644 index 0000000..2f8c0f2 --- /dev/null +++ b/images/add_bottom.png Binary files differ diff --git a/images/add_top.png b/images/add_top.png new file mode 100644 index 0000000..a5ceb4f --- /dev/null +++ b/images/add_top.png Binary files differ diff --git a/images/chart.png b/images/chart.png new file mode 100644 index 0000000..e7871bd --- /dev/null +++ b/images/chart.png Binary files differ diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/PhaseWindow.h b/PhaseWindow.h index bfb44b6..6fc532c 100644 --- a/PhaseWindow.h +++ b/PhaseWindow.h @@ -25,13 +25,14 @@ void drawPhaseDataOnPage(PhaseDataDto * phaseData); private slots: - void on_minButt_clicked(); - void on_exitButt_clicked(); - void on_startButt_clicked(); void on_endButt_clicked(); void on_settingButt_clicked(); + void buttonClick(); + void on_btnMenuMin_clicked(); + void on_btnMenuClose_clicked(); + private: Ui::PhaseWindow *ui; QList channelGroupList; @@ -39,10 +40,12 @@ PhaseDevice * device; - + void initForm(); + void initDeivce(); void createFolder(); void generateWidgetForDevice(); void updateChannelActive(QList channelActive); + void swiftConntrollerButt(); }; #endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui index d25b82b..66d8d47 100644 --- a/PhaseWindow.ui +++ b/PhaseWindow.ui @@ -6,840 +6,1018 @@ 0 0 - 1366 + 1200 720 - 1366 + 1200 0 比相仪测量软件 - - - - 0 - 100 - 100 - 30 - + + + 0 - - - 微软雅黑 - 10 - + + 1 - - QFrame::NoFrame + + 1 - - Qt::ScrollBarAlwaysOff + + 1 - - true + + 1 - - - - 0 - 0 - 100 - 30 - - - - - - - - 1300 - 10 - 40 - 40 - - - - - - - 退出 - - - - - - 0 - 0 - 200 - 50 - - - - - 微软雅黑 - 16 - - - - 比相仪测量软件 - - - Qt::AlignCenter - - - - - - 0 - 90 - 1371 - 16 - - - - QFrame::Plain - - - Qt::Horizontal - - - - - - 1250 - 10 - 40 - 40 - - - - - - - 最小化 - - - - - - 1200 - 10 - 40 - 40 - - - - - - - 配置 - - - - - - 0 - 50 - 240 - 40 - - - - - 微软雅黑 - 12 - 75 - true - - - - Qt::RightToLeft - - - 2021-12-10 10:00:00 - - - Qt::AlignCenter - - - - - - 230 - 35 - 941 - 40 - - - - - 1 - - - - - + + + + + 0 + 0 + + + + + 5 - - :/points/images/green.png + + 20 - - Qt::AlignCenter + + 0 + + + 0 + + + 0 + + + + + + + + Qt::AlignCenter + + + + + + + 0 + + + 10 + + + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + + + + 0 + + + 40 + + + + + + 705 + 0 + + + + + 780 + 30 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + 705 + 0 + + + + + 780 + 40 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 开始测量 + + + + :/images/start.png:/images/start.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 停止测量 + + + + :/images/stop.png:/images/stop.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 系统设置 + + + + :/images/config.png:/images/config.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + 0 + + + 0 + + + 10 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 关闭 + + + + + + + + + + Qt::Vertical + + + + 60 + 37 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 最小化 + + + + + + + + + + + + + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 1198 + 651 + - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - 230 - 65 - 941 - 30 - - - - - 0 - - - 0 - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 1 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 2 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 3 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 4 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 5 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 6 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 7 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 8 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 9 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 10 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 11 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 12 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 13 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 14 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 15 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 16 - - - Qt::AlignCenter - - - - - - - - - 1100 - 10 - 40 - 40 - - - - - - - 开始 - - - - - - 1150 - 10 - 40 - 40 - - - - - - - 结束 - - + + + diff --git a/images.qrc b/images.qrc index 0fc1f3e..08fb3f8 100644 --- a/images.qrc +++ b/images.qrc @@ -3,4 +3,18 @@ images/white.png images/green.png + + images/fontawesome-webfont.ttf + images/main_config.png + images/phaseMeasure.png + images/config.png + images/start.png + images/stop.png + images/chart.png + images/clear.png + + + images/add_bottom.png + images/add_top.png + diff --git a/images/add_bottom.png b/images/add_bottom.png new file mode 100644 index 0000000..2f8c0f2 --- /dev/null +++ b/images/add_bottom.png Binary files differ diff --git a/images/add_top.png b/images/add_top.png new file mode 100644 index 0000000..a5ceb4f --- /dev/null +++ b/images/add_top.png Binary files differ diff --git a/images/chart.png b/images/chart.png new file mode 100644 index 0000000..e7871bd --- /dev/null +++ b/images/chart.png Binary files differ diff --git a/images/clear.png b/images/clear.png new file mode 100644 index 0000000..b825e6d --- /dev/null +++ b/images/clear.png Binary files differ diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/PhaseWindow.h b/PhaseWindow.h index bfb44b6..6fc532c 100644 --- a/PhaseWindow.h +++ b/PhaseWindow.h @@ -25,13 +25,14 @@ void drawPhaseDataOnPage(PhaseDataDto * phaseData); private slots: - void on_minButt_clicked(); - void on_exitButt_clicked(); - void on_startButt_clicked(); void on_endButt_clicked(); void on_settingButt_clicked(); + void buttonClick(); + void on_btnMenuMin_clicked(); + void on_btnMenuClose_clicked(); + private: Ui::PhaseWindow *ui; QList channelGroupList; @@ -39,10 +40,12 @@ PhaseDevice * device; - + void initForm(); + void initDeivce(); void createFolder(); void generateWidgetForDevice(); void updateChannelActive(QList channelActive); + void swiftConntrollerButt(); }; #endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui index d25b82b..66d8d47 100644 --- a/PhaseWindow.ui +++ b/PhaseWindow.ui @@ -6,840 +6,1018 @@ 0 0 - 1366 + 1200 720 - 1366 + 1200 0 比相仪测量软件 - - - - 0 - 100 - 100 - 30 - + + + 0 - - - 微软雅黑 - 10 - + + 1 - - QFrame::NoFrame + + 1 - - Qt::ScrollBarAlwaysOff + + 1 - - true + + 1 - - - - 0 - 0 - 100 - 30 - - - - - - - - 1300 - 10 - 40 - 40 - - - - - - - 退出 - - - - - - 0 - 0 - 200 - 50 - - - - - 微软雅黑 - 16 - - - - 比相仪测量软件 - - - Qt::AlignCenter - - - - - - 0 - 90 - 1371 - 16 - - - - QFrame::Plain - - - Qt::Horizontal - - - - - - 1250 - 10 - 40 - 40 - - - - - - - 最小化 - - - - - - 1200 - 10 - 40 - 40 - - - - - - - 配置 - - - - - - 0 - 50 - 240 - 40 - - - - - 微软雅黑 - 12 - 75 - true - - - - Qt::RightToLeft - - - 2021-12-10 10:00:00 - - - Qt::AlignCenter - - - - - - 230 - 35 - 941 - 40 - - - - - 1 - - - - - + + + + + 0 + 0 + + + + + 5 - - :/points/images/green.png + + 20 - - Qt::AlignCenter + + 0 + + + 0 + + + 0 + + + + + + + + Qt::AlignCenter + + + + + + + 0 + + + 10 + + + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + + + + 0 + + + 40 + + + + + + 705 + 0 + + + + + 780 + 30 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + 705 + 0 + + + + + 780 + 40 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 开始测量 + + + + :/images/start.png:/images/start.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 停止测量 + + + + :/images/stop.png:/images/stop.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 系统设置 + + + + :/images/config.png:/images/config.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + 0 + + + 0 + + + 10 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 关闭 + + + + + + + + + + Qt::Vertical + + + + 60 + 37 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 最小化 + + + + + + + + + + + + + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 1198 + 651 + - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - 230 - 65 - 941 - 30 - - - - - 0 - - - 0 - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 1 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 2 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 3 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 4 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 5 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 6 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 7 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 8 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 9 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 10 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 11 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 12 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 13 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 14 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 15 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 16 - - - Qt::AlignCenter - - - - - - - - - 1100 - 10 - 40 - 40 - - - - - - - 开始 - - - - - - 1150 - 10 - 40 - 40 - - - - - - - 结束 - - + + + diff --git a/images.qrc b/images.qrc index 0fc1f3e..08fb3f8 100644 --- a/images.qrc +++ b/images.qrc @@ -3,4 +3,18 @@ images/white.png images/green.png + + images/fontawesome-webfont.ttf + images/main_config.png + images/phaseMeasure.png + images/config.png + images/start.png + images/stop.png + images/chart.png + images/clear.png + + + images/add_bottom.png + images/add_top.png + diff --git a/images/add_bottom.png b/images/add_bottom.png new file mode 100644 index 0000000..2f8c0f2 --- /dev/null +++ b/images/add_bottom.png Binary files differ diff --git a/images/add_top.png b/images/add_top.png new file mode 100644 index 0000000..a5ceb4f --- /dev/null +++ b/images/add_top.png Binary files differ diff --git a/images/chart.png b/images/chart.png new file mode 100644 index 0000000..e7871bd --- /dev/null +++ b/images/chart.png Binary files differ diff --git a/images/clear.png b/images/clear.png new file mode 100644 index 0000000..b825e6d --- /dev/null +++ b/images/clear.png Binary files differ diff --git a/images/config.png b/images/config.png new file mode 100644 index 0000000..55aaccc --- /dev/null +++ b/images/config.png Binary files differ diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/PhaseWindow.h b/PhaseWindow.h index bfb44b6..6fc532c 100644 --- a/PhaseWindow.h +++ b/PhaseWindow.h @@ -25,13 +25,14 @@ void drawPhaseDataOnPage(PhaseDataDto * phaseData); private slots: - void on_minButt_clicked(); - void on_exitButt_clicked(); - void on_startButt_clicked(); void on_endButt_clicked(); void on_settingButt_clicked(); + void buttonClick(); + void on_btnMenuMin_clicked(); + void on_btnMenuClose_clicked(); + private: Ui::PhaseWindow *ui; QList channelGroupList; @@ -39,10 +40,12 @@ PhaseDevice * device; - + void initForm(); + void initDeivce(); void createFolder(); void generateWidgetForDevice(); void updateChannelActive(QList channelActive); + void swiftConntrollerButt(); }; #endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui index d25b82b..66d8d47 100644 --- a/PhaseWindow.ui +++ b/PhaseWindow.ui @@ -6,840 +6,1018 @@ 0 0 - 1366 + 1200 720 - 1366 + 1200 0 比相仪测量软件 - - - - 0 - 100 - 100 - 30 - + + + 0 - - - 微软雅黑 - 10 - + + 1 - - QFrame::NoFrame + + 1 - - Qt::ScrollBarAlwaysOff + + 1 - - true + + 1 - - - - 0 - 0 - 100 - 30 - - - - - - - - 1300 - 10 - 40 - 40 - - - - - - - 退出 - - - - - - 0 - 0 - 200 - 50 - - - - - 微软雅黑 - 16 - - - - 比相仪测量软件 - - - Qt::AlignCenter - - - - - - 0 - 90 - 1371 - 16 - - - - QFrame::Plain - - - Qt::Horizontal - - - - - - 1250 - 10 - 40 - 40 - - - - - - - 最小化 - - - - - - 1200 - 10 - 40 - 40 - - - - - - - 配置 - - - - - - 0 - 50 - 240 - 40 - - - - - 微软雅黑 - 12 - 75 - true - - - - Qt::RightToLeft - - - 2021-12-10 10:00:00 - - - Qt::AlignCenter - - - - - - 230 - 35 - 941 - 40 - - - - - 1 - - - - - + + + + + 0 + 0 + + + + + 5 - - :/points/images/green.png + + 20 - - Qt::AlignCenter + + 0 + + + 0 + + + 0 + + + + + + + + Qt::AlignCenter + + + + + + + 0 + + + 10 + + + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + + + + 0 + + + 40 + + + + + + 705 + 0 + + + + + 780 + 30 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + 705 + 0 + + + + + 780 + 40 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 开始测量 + + + + :/images/start.png:/images/start.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 停止测量 + + + + :/images/stop.png:/images/stop.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 系统设置 + + + + :/images/config.png:/images/config.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + 0 + + + 0 + + + 10 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 关闭 + + + + + + + + + + Qt::Vertical + + + + 60 + 37 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 最小化 + + + + + + + + + + + + + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 1198 + 651 + - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - 230 - 65 - 941 - 30 - - - - - 0 - - - 0 - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 1 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 2 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 3 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 4 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 5 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 6 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 7 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 8 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 9 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 10 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 11 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 12 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 13 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 14 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 15 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 16 - - - Qt::AlignCenter - - - - - - - - - 1100 - 10 - 40 - 40 - - - - - - - 开始 - - - - - - 1150 - 10 - 40 - 40 - - - - - - - 结束 - - + + + diff --git a/images.qrc b/images.qrc index 0fc1f3e..08fb3f8 100644 --- a/images.qrc +++ b/images.qrc @@ -3,4 +3,18 @@ images/white.png images/green.png + + images/fontawesome-webfont.ttf + images/main_config.png + images/phaseMeasure.png + images/config.png + images/start.png + images/stop.png + images/chart.png + images/clear.png + + + images/add_bottom.png + images/add_top.png + diff --git a/images/add_bottom.png b/images/add_bottom.png new file mode 100644 index 0000000..2f8c0f2 --- /dev/null +++ b/images/add_bottom.png Binary files differ diff --git a/images/add_top.png b/images/add_top.png new file mode 100644 index 0000000..a5ceb4f --- /dev/null +++ b/images/add_top.png Binary files differ diff --git a/images/chart.png b/images/chart.png new file mode 100644 index 0000000..e7871bd --- /dev/null +++ b/images/chart.png Binary files differ diff --git a/images/clear.png b/images/clear.png new file mode 100644 index 0000000..b825e6d --- /dev/null +++ b/images/clear.png Binary files differ diff --git a/images/config.png b/images/config.png new file mode 100644 index 0000000..55aaccc --- /dev/null +++ b/images/config.png Binary files differ diff --git a/images/fontawesome-webfont.ttf b/images/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 --- /dev/null +++ b/images/fontawesome-webfont.ttf Binary files differ diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/PhaseWindow.h b/PhaseWindow.h index bfb44b6..6fc532c 100644 --- a/PhaseWindow.h +++ b/PhaseWindow.h @@ -25,13 +25,14 @@ void drawPhaseDataOnPage(PhaseDataDto * phaseData); private slots: - void on_minButt_clicked(); - void on_exitButt_clicked(); - void on_startButt_clicked(); void on_endButt_clicked(); void on_settingButt_clicked(); + void buttonClick(); + void on_btnMenuMin_clicked(); + void on_btnMenuClose_clicked(); + private: Ui::PhaseWindow *ui; QList channelGroupList; @@ -39,10 +40,12 @@ PhaseDevice * device; - + void initForm(); + void initDeivce(); void createFolder(); void generateWidgetForDevice(); void updateChannelActive(QList channelActive); + void swiftConntrollerButt(); }; #endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui index d25b82b..66d8d47 100644 --- a/PhaseWindow.ui +++ b/PhaseWindow.ui @@ -6,840 +6,1018 @@ 0 0 - 1366 + 1200 720 - 1366 + 1200 0 比相仪测量软件 - - - - 0 - 100 - 100 - 30 - + + + 0 - - - 微软雅黑 - 10 - + + 1 - - QFrame::NoFrame + + 1 - - Qt::ScrollBarAlwaysOff + + 1 - - true + + 1 - - - - 0 - 0 - 100 - 30 - - - - - - - - 1300 - 10 - 40 - 40 - - - - - - - 退出 - - - - - - 0 - 0 - 200 - 50 - - - - - 微软雅黑 - 16 - - - - 比相仪测量软件 - - - Qt::AlignCenter - - - - - - 0 - 90 - 1371 - 16 - - - - QFrame::Plain - - - Qt::Horizontal - - - - - - 1250 - 10 - 40 - 40 - - - - - - - 最小化 - - - - - - 1200 - 10 - 40 - 40 - - - - - - - 配置 - - - - - - 0 - 50 - 240 - 40 - - - - - 微软雅黑 - 12 - 75 - true - - - - Qt::RightToLeft - - - 2021-12-10 10:00:00 - - - Qt::AlignCenter - - - - - - 230 - 35 - 941 - 40 - - - - - 1 - - - - - + + + + + 0 + 0 + + + + + 5 - - :/points/images/green.png + + 20 - - Qt::AlignCenter + + 0 + + + 0 + + + 0 + + + + + + + + Qt::AlignCenter + + + + + + + 0 + + + 10 + + + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + + + + 0 + + + 40 + + + + + + 705 + 0 + + + + + 780 + 30 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + 705 + 0 + + + + + 780 + 40 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 开始测量 + + + + :/images/start.png:/images/start.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 停止测量 + + + + :/images/stop.png:/images/stop.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 系统设置 + + + + :/images/config.png:/images/config.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + 0 + + + 0 + + + 10 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 关闭 + + + + + + + + + + Qt::Vertical + + + + 60 + 37 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 最小化 + + + + + + + + + + + + + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 1198 + 651 + - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - 230 - 65 - 941 - 30 - - - - - 0 - - - 0 - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 1 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 2 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 3 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 4 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 5 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 6 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 7 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 8 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 9 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 10 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 11 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 12 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 13 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 14 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 15 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 16 - - - Qt::AlignCenter - - - - - - - - - 1100 - 10 - 40 - 40 - - - - - - - 开始 - - - - - - 1150 - 10 - 40 - 40 - - - - - - - 结束 - - + + + diff --git a/images.qrc b/images.qrc index 0fc1f3e..08fb3f8 100644 --- a/images.qrc +++ b/images.qrc @@ -3,4 +3,18 @@ images/white.png images/green.png + + images/fontawesome-webfont.ttf + images/main_config.png + images/phaseMeasure.png + images/config.png + images/start.png + images/stop.png + images/chart.png + images/clear.png + + + images/add_bottom.png + images/add_top.png + diff --git a/images/add_bottom.png b/images/add_bottom.png new file mode 100644 index 0000000..2f8c0f2 --- /dev/null +++ b/images/add_bottom.png Binary files differ diff --git a/images/add_top.png b/images/add_top.png new file mode 100644 index 0000000..a5ceb4f --- /dev/null +++ b/images/add_top.png Binary files differ diff --git a/images/chart.png b/images/chart.png new file mode 100644 index 0000000..e7871bd --- /dev/null +++ b/images/chart.png Binary files differ diff --git a/images/clear.png b/images/clear.png new file mode 100644 index 0000000..b825e6d --- /dev/null +++ b/images/clear.png Binary files differ diff --git a/images/config.png b/images/config.png new file mode 100644 index 0000000..55aaccc --- /dev/null +++ b/images/config.png Binary files differ diff --git a/images/fontawesome-webfont.ttf b/images/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 --- /dev/null +++ b/images/fontawesome-webfont.ttf Binary files differ diff --git a/images/green.png b/images/green.png index a33ee4b..369e54f 100644 --- a/images/green.png +++ b/images/green.png Binary files differ diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/PhaseWindow.h b/PhaseWindow.h index bfb44b6..6fc532c 100644 --- a/PhaseWindow.h +++ b/PhaseWindow.h @@ -25,13 +25,14 @@ void drawPhaseDataOnPage(PhaseDataDto * phaseData); private slots: - void on_minButt_clicked(); - void on_exitButt_clicked(); - void on_startButt_clicked(); void on_endButt_clicked(); void on_settingButt_clicked(); + void buttonClick(); + void on_btnMenuMin_clicked(); + void on_btnMenuClose_clicked(); + private: Ui::PhaseWindow *ui; QList channelGroupList; @@ -39,10 +40,12 @@ PhaseDevice * device; - + void initForm(); + void initDeivce(); void createFolder(); void generateWidgetForDevice(); void updateChannelActive(QList channelActive); + void swiftConntrollerButt(); }; #endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui index d25b82b..66d8d47 100644 --- a/PhaseWindow.ui +++ b/PhaseWindow.ui @@ -6,840 +6,1018 @@ 0 0 - 1366 + 1200 720 - 1366 + 1200 0 比相仪测量软件 - - - - 0 - 100 - 100 - 30 - + + + 0 - - - 微软雅黑 - 10 - + + 1 - - QFrame::NoFrame + + 1 - - Qt::ScrollBarAlwaysOff + + 1 - - true + + 1 - - - - 0 - 0 - 100 - 30 - - - - - - - - 1300 - 10 - 40 - 40 - - - - - - - 退出 - - - - - - 0 - 0 - 200 - 50 - - - - - 微软雅黑 - 16 - - - - 比相仪测量软件 - - - Qt::AlignCenter - - - - - - 0 - 90 - 1371 - 16 - - - - QFrame::Plain - - - Qt::Horizontal - - - - - - 1250 - 10 - 40 - 40 - - - - - - - 最小化 - - - - - - 1200 - 10 - 40 - 40 - - - - - - - 配置 - - - - - - 0 - 50 - 240 - 40 - - - - - 微软雅黑 - 12 - 75 - true - - - - Qt::RightToLeft - - - 2021-12-10 10:00:00 - - - Qt::AlignCenter - - - - - - 230 - 35 - 941 - 40 - - - - - 1 - - - - - + + + + + 0 + 0 + + + + + 5 - - :/points/images/green.png + + 20 - - Qt::AlignCenter + + 0 + + + 0 + + + 0 + + + + + + + + Qt::AlignCenter + + + + + + + 0 + + + 10 + + + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + + + + 0 + + + 40 + + + + + + 705 + 0 + + + + + 780 + 30 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + 705 + 0 + + + + + 780 + 40 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 开始测量 + + + + :/images/start.png:/images/start.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 停止测量 + + + + :/images/stop.png:/images/stop.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 系统设置 + + + + :/images/config.png:/images/config.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + 0 + + + 0 + + + 10 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 关闭 + + + + + + + + + + Qt::Vertical + + + + 60 + 37 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 最小化 + + + + + + + + + + + + + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 1198 + 651 + - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - 230 - 65 - 941 - 30 - - - - - 0 - - - 0 - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 1 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 2 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 3 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 4 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 5 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 6 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 7 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 8 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 9 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 10 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 11 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 12 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 13 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 14 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 15 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 16 - - - Qt::AlignCenter - - - - - - - - - 1100 - 10 - 40 - 40 - - - - - - - 开始 - - - - - - 1150 - 10 - 40 - 40 - - - - - - - 结束 - - + + + diff --git a/images.qrc b/images.qrc index 0fc1f3e..08fb3f8 100644 --- a/images.qrc +++ b/images.qrc @@ -3,4 +3,18 @@ images/white.png images/green.png + + images/fontawesome-webfont.ttf + images/main_config.png + images/phaseMeasure.png + images/config.png + images/start.png + images/stop.png + images/chart.png + images/clear.png + + + images/add_bottom.png + images/add_top.png + diff --git a/images/add_bottom.png b/images/add_bottom.png new file mode 100644 index 0000000..2f8c0f2 --- /dev/null +++ b/images/add_bottom.png Binary files differ diff --git a/images/add_top.png b/images/add_top.png new file mode 100644 index 0000000..a5ceb4f --- /dev/null +++ b/images/add_top.png Binary files differ diff --git a/images/chart.png b/images/chart.png new file mode 100644 index 0000000..e7871bd --- /dev/null +++ b/images/chart.png Binary files differ diff --git a/images/clear.png b/images/clear.png new file mode 100644 index 0000000..b825e6d --- /dev/null +++ b/images/clear.png Binary files differ diff --git a/images/config.png b/images/config.png new file mode 100644 index 0000000..55aaccc --- /dev/null +++ b/images/config.png Binary files differ diff --git a/images/fontawesome-webfont.ttf b/images/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 --- /dev/null +++ b/images/fontawesome-webfont.ttf Binary files differ diff --git a/images/green.png b/images/green.png index a33ee4b..369e54f 100644 --- a/images/green.png +++ b/images/green.png Binary files differ diff --git a/images/main_config.png b/images/main_config.png new file mode 100644 index 0000000..d45b094 --- /dev/null +++ b/images/main_config.png Binary files differ diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/PhaseWindow.h b/PhaseWindow.h index bfb44b6..6fc532c 100644 --- a/PhaseWindow.h +++ b/PhaseWindow.h @@ -25,13 +25,14 @@ void drawPhaseDataOnPage(PhaseDataDto * phaseData); private slots: - void on_minButt_clicked(); - void on_exitButt_clicked(); - void on_startButt_clicked(); void on_endButt_clicked(); void on_settingButt_clicked(); + void buttonClick(); + void on_btnMenuMin_clicked(); + void on_btnMenuClose_clicked(); + private: Ui::PhaseWindow *ui; QList channelGroupList; @@ -39,10 +40,12 @@ PhaseDevice * device; - + void initForm(); + void initDeivce(); void createFolder(); void generateWidgetForDevice(); void updateChannelActive(QList channelActive); + void swiftConntrollerButt(); }; #endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui index d25b82b..66d8d47 100644 --- a/PhaseWindow.ui +++ b/PhaseWindow.ui @@ -6,840 +6,1018 @@ 0 0 - 1366 + 1200 720 - 1366 + 1200 0 比相仪测量软件 - - - - 0 - 100 - 100 - 30 - + + + 0 - - - 微软雅黑 - 10 - + + 1 - - QFrame::NoFrame + + 1 - - Qt::ScrollBarAlwaysOff + + 1 - - true + + 1 - - - - 0 - 0 - 100 - 30 - - - - - - - - 1300 - 10 - 40 - 40 - - - - - - - 退出 - - - - - - 0 - 0 - 200 - 50 - - - - - 微软雅黑 - 16 - - - - 比相仪测量软件 - - - Qt::AlignCenter - - - - - - 0 - 90 - 1371 - 16 - - - - QFrame::Plain - - - Qt::Horizontal - - - - - - 1250 - 10 - 40 - 40 - - - - - - - 最小化 - - - - - - 1200 - 10 - 40 - 40 - - - - - - - 配置 - - - - - - 0 - 50 - 240 - 40 - - - - - 微软雅黑 - 12 - 75 - true - - - - Qt::RightToLeft - - - 2021-12-10 10:00:00 - - - Qt::AlignCenter - - - - - - 230 - 35 - 941 - 40 - - - - - 1 - - - - - + + + + + 0 + 0 + + + + + 5 - - :/points/images/green.png + + 20 - - Qt::AlignCenter + + 0 + + + 0 + + + 0 + + + + + + + + Qt::AlignCenter + + + + + + + 0 + + + 10 + + + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + + + + 0 + + + 40 + + + + + + 705 + 0 + + + + + 780 + 30 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + 705 + 0 + + + + + 780 + 40 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 开始测量 + + + + :/images/start.png:/images/start.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 停止测量 + + + + :/images/stop.png:/images/stop.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 系统设置 + + + + :/images/config.png:/images/config.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + 0 + + + 0 + + + 10 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 关闭 + + + + + + + + + + Qt::Vertical + + + + 60 + 37 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 最小化 + + + + + + + + + + + + + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 1198 + 651 + - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - 230 - 65 - 941 - 30 - - - - - 0 - - - 0 - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 1 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 2 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 3 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 4 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 5 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 6 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 7 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 8 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 9 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 10 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 11 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 12 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 13 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 14 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 15 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 16 - - - Qt::AlignCenter - - - - - - - - - 1100 - 10 - 40 - 40 - - - - - - - 开始 - - - - - - 1150 - 10 - 40 - 40 - - - - - - - 结束 - - + + + diff --git a/images.qrc b/images.qrc index 0fc1f3e..08fb3f8 100644 --- a/images.qrc +++ b/images.qrc @@ -3,4 +3,18 @@ images/white.png images/green.png + + images/fontawesome-webfont.ttf + images/main_config.png + images/phaseMeasure.png + images/config.png + images/start.png + images/stop.png + images/chart.png + images/clear.png + + + images/add_bottom.png + images/add_top.png + diff --git a/images/add_bottom.png b/images/add_bottom.png new file mode 100644 index 0000000..2f8c0f2 --- /dev/null +++ b/images/add_bottom.png Binary files differ diff --git a/images/add_top.png b/images/add_top.png new file mode 100644 index 0000000..a5ceb4f --- /dev/null +++ b/images/add_top.png Binary files differ diff --git a/images/chart.png b/images/chart.png new file mode 100644 index 0000000..e7871bd --- /dev/null +++ b/images/chart.png Binary files differ diff --git a/images/clear.png b/images/clear.png new file mode 100644 index 0000000..b825e6d --- /dev/null +++ b/images/clear.png Binary files differ diff --git a/images/config.png b/images/config.png new file mode 100644 index 0000000..55aaccc --- /dev/null +++ b/images/config.png Binary files differ diff --git a/images/fontawesome-webfont.ttf b/images/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 --- /dev/null +++ b/images/fontawesome-webfont.ttf Binary files differ diff --git a/images/green.png b/images/green.png index a33ee4b..369e54f 100644 --- a/images/green.png +++ b/images/green.png Binary files differ diff --git a/images/main_config.png b/images/main_config.png new file mode 100644 index 0000000..d45b094 --- /dev/null +++ b/images/main_config.png Binary files differ diff --git a/images/phaseMeasure.png b/images/phaseMeasure.png new file mode 100644 index 0000000..184237b --- /dev/null +++ b/images/phaseMeasure.png Binary files differ diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/PhaseWindow.h b/PhaseWindow.h index bfb44b6..6fc532c 100644 --- a/PhaseWindow.h +++ b/PhaseWindow.h @@ -25,13 +25,14 @@ void drawPhaseDataOnPage(PhaseDataDto * phaseData); private slots: - void on_minButt_clicked(); - void on_exitButt_clicked(); - void on_startButt_clicked(); void on_endButt_clicked(); void on_settingButt_clicked(); + void buttonClick(); + void on_btnMenuMin_clicked(); + void on_btnMenuClose_clicked(); + private: Ui::PhaseWindow *ui; QList channelGroupList; @@ -39,10 +40,12 @@ PhaseDevice * device; - + void initForm(); + void initDeivce(); void createFolder(); void generateWidgetForDevice(); void updateChannelActive(QList channelActive); + void swiftConntrollerButt(); }; #endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui index d25b82b..66d8d47 100644 --- a/PhaseWindow.ui +++ b/PhaseWindow.ui @@ -6,840 +6,1018 @@ 0 0 - 1366 + 1200 720 - 1366 + 1200 0 比相仪测量软件 - - - - 0 - 100 - 100 - 30 - + + + 0 - - - 微软雅黑 - 10 - + + 1 - - QFrame::NoFrame + + 1 - - Qt::ScrollBarAlwaysOff + + 1 - - true + + 1 - - - - 0 - 0 - 100 - 30 - - - - - - - - 1300 - 10 - 40 - 40 - - - - - - - 退出 - - - - - - 0 - 0 - 200 - 50 - - - - - 微软雅黑 - 16 - - - - 比相仪测量软件 - - - Qt::AlignCenter - - - - - - 0 - 90 - 1371 - 16 - - - - QFrame::Plain - - - Qt::Horizontal - - - - - - 1250 - 10 - 40 - 40 - - - - - - - 最小化 - - - - - - 1200 - 10 - 40 - 40 - - - - - - - 配置 - - - - - - 0 - 50 - 240 - 40 - - - - - 微软雅黑 - 12 - 75 - true - - - - Qt::RightToLeft - - - 2021-12-10 10:00:00 - - - Qt::AlignCenter - - - - - - 230 - 35 - 941 - 40 - - - - - 1 - - - - - + + + + + 0 + 0 + + + + + 5 - - :/points/images/green.png + + 20 - - Qt::AlignCenter + + 0 + + + 0 + + + 0 + + + + + + + + Qt::AlignCenter + + + + + + + 0 + + + 10 + + + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + + + + 0 + + + 40 + + + + + + 705 + 0 + + + + + 780 + 30 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + 705 + 0 + + + + + 780 + 40 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 开始测量 + + + + :/images/start.png:/images/start.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 停止测量 + + + + :/images/stop.png:/images/stop.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 系统设置 + + + + :/images/config.png:/images/config.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + 0 + + + 0 + + + 10 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 关闭 + + + + + + + + + + Qt::Vertical + + + + 60 + 37 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 最小化 + + + + + + + + + + + + + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 1198 + 651 + - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - 230 - 65 - 941 - 30 - - - - - 0 - - - 0 - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 1 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 2 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 3 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 4 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 5 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 6 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 7 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 8 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 9 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 10 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 11 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 12 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 13 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 14 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 15 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 16 - - - Qt::AlignCenter - - - - - - - - - 1100 - 10 - 40 - 40 - - - - - - - 开始 - - - - - - 1150 - 10 - 40 - 40 - - - - - - - 结束 - - + + + diff --git a/images.qrc b/images.qrc index 0fc1f3e..08fb3f8 100644 --- a/images.qrc +++ b/images.qrc @@ -3,4 +3,18 @@ images/white.png images/green.png + + images/fontawesome-webfont.ttf + images/main_config.png + images/phaseMeasure.png + images/config.png + images/start.png + images/stop.png + images/chart.png + images/clear.png + + + images/add_bottom.png + images/add_top.png + diff --git a/images/add_bottom.png b/images/add_bottom.png new file mode 100644 index 0000000..2f8c0f2 --- /dev/null +++ b/images/add_bottom.png Binary files differ diff --git a/images/add_top.png b/images/add_top.png new file mode 100644 index 0000000..a5ceb4f --- /dev/null +++ b/images/add_top.png Binary files differ diff --git a/images/chart.png b/images/chart.png new file mode 100644 index 0000000..e7871bd --- /dev/null +++ b/images/chart.png Binary files differ diff --git a/images/clear.png b/images/clear.png new file mode 100644 index 0000000..b825e6d --- /dev/null +++ b/images/clear.png Binary files differ diff --git a/images/config.png b/images/config.png new file mode 100644 index 0000000..55aaccc --- /dev/null +++ b/images/config.png Binary files differ diff --git a/images/fontawesome-webfont.ttf b/images/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 --- /dev/null +++ b/images/fontawesome-webfont.ttf Binary files differ diff --git a/images/green.png b/images/green.png index a33ee4b..369e54f 100644 --- a/images/green.png +++ b/images/green.png Binary files differ diff --git a/images/main_config.png b/images/main_config.png new file mode 100644 index 0000000..d45b094 --- /dev/null +++ b/images/main_config.png Binary files differ diff --git a/images/phaseMeasure.png b/images/phaseMeasure.png new file mode 100644 index 0000000..184237b --- /dev/null +++ b/images/phaseMeasure.png Binary files differ diff --git a/images/start.png b/images/start.png new file mode 100644 index 0000000..725c304 --- /dev/null +++ b/images/start.png Binary files differ diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/PhaseWindow.h b/PhaseWindow.h index bfb44b6..6fc532c 100644 --- a/PhaseWindow.h +++ b/PhaseWindow.h @@ -25,13 +25,14 @@ void drawPhaseDataOnPage(PhaseDataDto * phaseData); private slots: - void on_minButt_clicked(); - void on_exitButt_clicked(); - void on_startButt_clicked(); void on_endButt_clicked(); void on_settingButt_clicked(); + void buttonClick(); + void on_btnMenuMin_clicked(); + void on_btnMenuClose_clicked(); + private: Ui::PhaseWindow *ui; QList channelGroupList; @@ -39,10 +40,12 @@ PhaseDevice * device; - + void initForm(); + void initDeivce(); void createFolder(); void generateWidgetForDevice(); void updateChannelActive(QList channelActive); + void swiftConntrollerButt(); }; #endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui index d25b82b..66d8d47 100644 --- a/PhaseWindow.ui +++ b/PhaseWindow.ui @@ -6,840 +6,1018 @@ 0 0 - 1366 + 1200 720 - 1366 + 1200 0 比相仪测量软件 - - - - 0 - 100 - 100 - 30 - + + + 0 - - - 微软雅黑 - 10 - + + 1 - - QFrame::NoFrame + + 1 - - Qt::ScrollBarAlwaysOff + + 1 - - true + + 1 - - - - 0 - 0 - 100 - 30 - - - - - - - - 1300 - 10 - 40 - 40 - - - - - - - 退出 - - - - - - 0 - 0 - 200 - 50 - - - - - 微软雅黑 - 16 - - - - 比相仪测量软件 - - - Qt::AlignCenter - - - - - - 0 - 90 - 1371 - 16 - - - - QFrame::Plain - - - Qt::Horizontal - - - - - - 1250 - 10 - 40 - 40 - - - - - - - 最小化 - - - - - - 1200 - 10 - 40 - 40 - - - - - - - 配置 - - - - - - 0 - 50 - 240 - 40 - - - - - 微软雅黑 - 12 - 75 - true - - - - Qt::RightToLeft - - - 2021-12-10 10:00:00 - - - Qt::AlignCenter - - - - - - 230 - 35 - 941 - 40 - - - - - 1 - - - - - + + + + + 0 + 0 + + + + + 5 - - :/points/images/green.png + + 20 - - Qt::AlignCenter + + 0 + + + 0 + + + 0 + + + + + + + + Qt::AlignCenter + + + + + + + 0 + + + 10 + + + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + + + + 0 + + + 40 + + + + + + 705 + 0 + + + + + 780 + 30 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + 705 + 0 + + + + + 780 + 40 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 开始测量 + + + + :/images/start.png:/images/start.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 停止测量 + + + + :/images/stop.png:/images/stop.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 系统设置 + + + + :/images/config.png:/images/config.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + 0 + + + 0 + + + 10 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 关闭 + + + + + + + + + + Qt::Vertical + + + + 60 + 37 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 最小化 + + + + + + + + + + + + + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 1198 + 651 + - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - 230 - 65 - 941 - 30 - - - - - 0 - - - 0 - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 1 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 2 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 3 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 4 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 5 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 6 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 7 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 8 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 9 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 10 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 11 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 12 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 13 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 14 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 15 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 16 - - - Qt::AlignCenter - - - - - - - - - 1100 - 10 - 40 - 40 - - - - - - - 开始 - - - - - - 1150 - 10 - 40 - 40 - - - - - - - 结束 - - + + + diff --git a/images.qrc b/images.qrc index 0fc1f3e..08fb3f8 100644 --- a/images.qrc +++ b/images.qrc @@ -3,4 +3,18 @@ images/white.png images/green.png + + images/fontawesome-webfont.ttf + images/main_config.png + images/phaseMeasure.png + images/config.png + images/start.png + images/stop.png + images/chart.png + images/clear.png + + + images/add_bottom.png + images/add_top.png + diff --git a/images/add_bottom.png b/images/add_bottom.png new file mode 100644 index 0000000..2f8c0f2 --- /dev/null +++ b/images/add_bottom.png Binary files differ diff --git a/images/add_top.png b/images/add_top.png new file mode 100644 index 0000000..a5ceb4f --- /dev/null +++ b/images/add_top.png Binary files differ diff --git a/images/chart.png b/images/chart.png new file mode 100644 index 0000000..e7871bd --- /dev/null +++ b/images/chart.png Binary files differ diff --git a/images/clear.png b/images/clear.png new file mode 100644 index 0000000..b825e6d --- /dev/null +++ b/images/clear.png Binary files differ diff --git a/images/config.png b/images/config.png new file mode 100644 index 0000000..55aaccc --- /dev/null +++ b/images/config.png Binary files differ diff --git a/images/fontawesome-webfont.ttf b/images/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 --- /dev/null +++ b/images/fontawesome-webfont.ttf Binary files differ diff --git a/images/green.png b/images/green.png index a33ee4b..369e54f 100644 --- a/images/green.png +++ b/images/green.png Binary files differ diff --git a/images/main_config.png b/images/main_config.png new file mode 100644 index 0000000..d45b094 --- /dev/null +++ b/images/main_config.png Binary files differ diff --git a/images/phaseMeasure.png b/images/phaseMeasure.png new file mode 100644 index 0000000..184237b --- /dev/null +++ b/images/phaseMeasure.png Binary files differ diff --git a/images/start.png b/images/start.png new file mode 100644 index 0000000..725c304 --- /dev/null +++ b/images/start.png Binary files differ diff --git a/images/stop.png b/images/stop.png new file mode 100644 index 0000000..2742084 --- /dev/null +++ b/images/stop.png Binary files differ diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/PhaseWindow.h b/PhaseWindow.h index bfb44b6..6fc532c 100644 --- a/PhaseWindow.h +++ b/PhaseWindow.h @@ -25,13 +25,14 @@ void drawPhaseDataOnPage(PhaseDataDto * phaseData); private slots: - void on_minButt_clicked(); - void on_exitButt_clicked(); - void on_startButt_clicked(); void on_endButt_clicked(); void on_settingButt_clicked(); + void buttonClick(); + void on_btnMenuMin_clicked(); + void on_btnMenuClose_clicked(); + private: Ui::PhaseWindow *ui; QList channelGroupList; @@ -39,10 +40,12 @@ PhaseDevice * device; - + void initForm(); + void initDeivce(); void createFolder(); void generateWidgetForDevice(); void updateChannelActive(QList channelActive); + void swiftConntrollerButt(); }; #endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui index d25b82b..66d8d47 100644 --- a/PhaseWindow.ui +++ b/PhaseWindow.ui @@ -6,840 +6,1018 @@ 0 0 - 1366 + 1200 720 - 1366 + 1200 0 比相仪测量软件 - - - - 0 - 100 - 100 - 30 - + + + 0 - - - 微软雅黑 - 10 - + + 1 - - QFrame::NoFrame + + 1 - - Qt::ScrollBarAlwaysOff + + 1 - - true + + 1 - - - - 0 - 0 - 100 - 30 - - - - - - - - 1300 - 10 - 40 - 40 - - - - - - - 退出 - - - - - - 0 - 0 - 200 - 50 - - - - - 微软雅黑 - 16 - - - - 比相仪测量软件 - - - Qt::AlignCenter - - - - - - 0 - 90 - 1371 - 16 - - - - QFrame::Plain - - - Qt::Horizontal - - - - - - 1250 - 10 - 40 - 40 - - - - - - - 最小化 - - - - - - 1200 - 10 - 40 - 40 - - - - - - - 配置 - - - - - - 0 - 50 - 240 - 40 - - - - - 微软雅黑 - 12 - 75 - true - - - - Qt::RightToLeft - - - 2021-12-10 10:00:00 - - - Qt::AlignCenter - - - - - - 230 - 35 - 941 - 40 - - - - - 1 - - - - - + + + + + 0 + 0 + + + + + 5 - - :/points/images/green.png + + 20 - - Qt::AlignCenter + + 0 + + + 0 + + + 0 + + + + + + + + Qt::AlignCenter + + + + + + + 0 + + + 10 + + + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + + + + 0 + + + 40 + + + + + + 705 + 0 + + + + + 780 + 30 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + 705 + 0 + + + + + 780 + 40 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 开始测量 + + + + :/images/start.png:/images/start.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 停止测量 + + + + :/images/stop.png:/images/stop.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 系统设置 + + + + :/images/config.png:/images/config.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + 0 + + + 0 + + + 10 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 关闭 + + + + + + + + + + Qt::Vertical + + + + 60 + 37 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 最小化 + + + + + + + + + + + + + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 1198 + 651 + - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - 230 - 65 - 941 - 30 - - - - - 0 - - - 0 - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 1 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 2 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 3 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 4 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 5 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 6 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 7 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 8 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 9 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 10 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 11 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 12 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 13 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 14 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 15 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 16 - - - Qt::AlignCenter - - - - - - - - - 1100 - 10 - 40 - 40 - - - - - - - 开始 - - - - - - 1150 - 10 - 40 - 40 - - - - - - - 结束 - - + + + diff --git a/images.qrc b/images.qrc index 0fc1f3e..08fb3f8 100644 --- a/images.qrc +++ b/images.qrc @@ -3,4 +3,18 @@ images/white.png images/green.png + + images/fontawesome-webfont.ttf + images/main_config.png + images/phaseMeasure.png + images/config.png + images/start.png + images/stop.png + images/chart.png + images/clear.png + + + images/add_bottom.png + images/add_top.png + diff --git a/images/add_bottom.png b/images/add_bottom.png new file mode 100644 index 0000000..2f8c0f2 --- /dev/null +++ b/images/add_bottom.png Binary files differ diff --git a/images/add_top.png b/images/add_top.png new file mode 100644 index 0000000..a5ceb4f --- /dev/null +++ b/images/add_top.png Binary files differ diff --git a/images/chart.png b/images/chart.png new file mode 100644 index 0000000..e7871bd --- /dev/null +++ b/images/chart.png Binary files differ diff --git a/images/clear.png b/images/clear.png new file mode 100644 index 0000000..b825e6d --- /dev/null +++ b/images/clear.png Binary files differ diff --git a/images/config.png b/images/config.png new file mode 100644 index 0000000..55aaccc --- /dev/null +++ b/images/config.png Binary files differ diff --git a/images/fontawesome-webfont.ttf b/images/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 --- /dev/null +++ b/images/fontawesome-webfont.ttf Binary files differ diff --git a/images/green.png b/images/green.png index a33ee4b..369e54f 100644 --- a/images/green.png +++ b/images/green.png Binary files differ diff --git a/images/main_config.png b/images/main_config.png new file mode 100644 index 0000000..d45b094 --- /dev/null +++ b/images/main_config.png Binary files differ diff --git a/images/phaseMeasure.png b/images/phaseMeasure.png new file mode 100644 index 0000000..184237b --- /dev/null +++ b/images/phaseMeasure.png Binary files differ diff --git a/images/start.png b/images/start.png new file mode 100644 index 0000000..725c304 --- /dev/null +++ b/images/start.png Binary files differ diff --git a/images/stop.png b/images/stop.png new file mode 100644 index 0000000..2742084 --- /dev/null +++ b/images/stop.png Binary files differ diff --git a/images/white.png b/images/white.png index 337df06..dc84601 100644 --- a/images/white.png +++ b/images/white.png Binary files differ diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/PhaseWindow.h b/PhaseWindow.h index bfb44b6..6fc532c 100644 --- a/PhaseWindow.h +++ b/PhaseWindow.h @@ -25,13 +25,14 @@ void drawPhaseDataOnPage(PhaseDataDto * phaseData); private slots: - void on_minButt_clicked(); - void on_exitButt_clicked(); - void on_startButt_clicked(); void on_endButt_clicked(); void on_settingButt_clicked(); + void buttonClick(); + void on_btnMenuMin_clicked(); + void on_btnMenuClose_clicked(); + private: Ui::PhaseWindow *ui; QList channelGroupList; @@ -39,10 +40,12 @@ PhaseDevice * device; - + void initForm(); + void initDeivce(); void createFolder(); void generateWidgetForDevice(); void updateChannelActive(QList channelActive); + void swiftConntrollerButt(); }; #endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui index d25b82b..66d8d47 100644 --- a/PhaseWindow.ui +++ b/PhaseWindow.ui @@ -6,840 +6,1018 @@ 0 0 - 1366 + 1200 720 - 1366 + 1200 0 比相仪测量软件 - - - - 0 - 100 - 100 - 30 - + + + 0 - - - 微软雅黑 - 10 - + + 1 - - QFrame::NoFrame + + 1 - - Qt::ScrollBarAlwaysOff + + 1 - - true + + 1 - - - - 0 - 0 - 100 - 30 - - - - - - - - 1300 - 10 - 40 - 40 - - - - - - - 退出 - - - - - - 0 - 0 - 200 - 50 - - - - - 微软雅黑 - 16 - - - - 比相仪测量软件 - - - Qt::AlignCenter - - - - - - 0 - 90 - 1371 - 16 - - - - QFrame::Plain - - - Qt::Horizontal - - - - - - 1250 - 10 - 40 - 40 - - - - - - - 最小化 - - - - - - 1200 - 10 - 40 - 40 - - - - - - - 配置 - - - - - - 0 - 50 - 240 - 40 - - - - - 微软雅黑 - 12 - 75 - true - - - - Qt::RightToLeft - - - 2021-12-10 10:00:00 - - - Qt::AlignCenter - - - - - - 230 - 35 - 941 - 40 - - - - - 1 - - - - - + + + + + 0 + 0 + + + + + 5 - - :/points/images/green.png + + 20 - - Qt::AlignCenter + + 0 + + + 0 + + + 0 + + + + + + + + Qt::AlignCenter + + + + + + + 0 + + + 10 + + + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + + + + 0 + + + 40 + + + + + + 705 + 0 + + + + + 780 + 30 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + 705 + 0 + + + + + 780 + 40 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 开始测量 + + + + :/images/start.png:/images/start.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 停止测量 + + + + :/images/stop.png:/images/stop.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 系统设置 + + + + :/images/config.png:/images/config.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + 0 + + + 0 + + + 10 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 关闭 + + + + + + + + + + Qt::Vertical + + + + 60 + 37 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 最小化 + + + + + + + + + + + + + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 1198 + 651 + - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - 230 - 65 - 941 - 30 - - - - - 0 - - - 0 - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 1 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 2 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 3 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 4 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 5 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 6 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 7 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 8 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 9 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 10 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 11 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 12 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 13 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 14 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 15 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 16 - - - Qt::AlignCenter - - - - - - - - - 1100 - 10 - 40 - 40 - - - - - - - 开始 - - - - - - 1150 - 10 - 40 - 40 - - - - - - - 结束 - - + + + diff --git a/images.qrc b/images.qrc index 0fc1f3e..08fb3f8 100644 --- a/images.qrc +++ b/images.qrc @@ -3,4 +3,18 @@ images/white.png images/green.png + + images/fontawesome-webfont.ttf + images/main_config.png + images/phaseMeasure.png + images/config.png + images/start.png + images/stop.png + images/chart.png + images/clear.png + + + images/add_bottom.png + images/add_top.png + diff --git a/images/add_bottom.png b/images/add_bottom.png new file mode 100644 index 0000000..2f8c0f2 --- /dev/null +++ b/images/add_bottom.png Binary files differ diff --git a/images/add_top.png b/images/add_top.png new file mode 100644 index 0000000..a5ceb4f --- /dev/null +++ b/images/add_top.png Binary files differ diff --git a/images/chart.png b/images/chart.png new file mode 100644 index 0000000..e7871bd --- /dev/null +++ b/images/chart.png Binary files differ diff --git a/images/clear.png b/images/clear.png new file mode 100644 index 0000000..b825e6d --- /dev/null +++ b/images/clear.png Binary files differ diff --git a/images/config.png b/images/config.png new file mode 100644 index 0000000..55aaccc --- /dev/null +++ b/images/config.png Binary files differ diff --git a/images/fontawesome-webfont.ttf b/images/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 --- /dev/null +++ b/images/fontawesome-webfont.ttf Binary files differ diff --git a/images/green.png b/images/green.png index a33ee4b..369e54f 100644 --- a/images/green.png +++ b/images/green.png Binary files differ diff --git a/images/main_config.png b/images/main_config.png new file mode 100644 index 0000000..d45b094 --- /dev/null +++ b/images/main_config.png Binary files differ diff --git a/images/phaseMeasure.png b/images/phaseMeasure.png new file mode 100644 index 0000000..184237b --- /dev/null +++ b/images/phaseMeasure.png Binary files differ diff --git a/images/start.png b/images/start.png new file mode 100644 index 0000000..725c304 --- /dev/null +++ b/images/start.png Binary files differ diff --git a/images/stop.png b/images/stop.png new file mode 100644 index 0000000..2742084 --- /dev/null +++ b/images/stop.png Binary files differ diff --git a/images/white.png b/images/white.png index 337df06..dc84601 100644 --- a/images/white.png +++ b/images/white.png Binary files differ diff --git a/main.cpp b/main.cpp index adf5eeb..382d44a 100644 --- a/main.cpp +++ b/main.cpp @@ -1,10 +1,32 @@ #include "PhaseWindow.h" - +#include "AppInit.h" #include +#include +#include int main(int argc, char *argv[]) { QApplication a(argc, argv); + + QTextCodec *codec = QTextCodec::codecForName("utf-8"); + QTextCodec::setCodecForLocale(codec); + + //加载样式表 + QFile file(QApplication::applicationDirPath() + "/qss/pmdark.css"); + if (file.open(QFile::ReadOnly)) { + QString qss = QLatin1String(file.readAll()); + QString paletteColor = qss.mid(20, 7); + qApp->setPalette(QPalette(QColor(paletteColor))); + qApp->setStyleSheet(qss); + file.close(); + } + + QFont font; + font.setFamily("Microsoft Yahei"); + font.setPixelSize(12); + a.setFont(font); + AppInit::Instance()->start(); + PhaseWindow w; w.show(); return a.exec(); diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/PhaseWindow.h b/PhaseWindow.h index bfb44b6..6fc532c 100644 --- a/PhaseWindow.h +++ b/PhaseWindow.h @@ -25,13 +25,14 @@ void drawPhaseDataOnPage(PhaseDataDto * phaseData); private slots: - void on_minButt_clicked(); - void on_exitButt_clicked(); - void on_startButt_clicked(); void on_endButt_clicked(); void on_settingButt_clicked(); + void buttonClick(); + void on_btnMenuMin_clicked(); + void on_btnMenuClose_clicked(); + private: Ui::PhaseWindow *ui; QList channelGroupList; @@ -39,10 +40,12 @@ PhaseDevice * device; - + void initForm(); + void initDeivce(); void createFolder(); void generateWidgetForDevice(); void updateChannelActive(QList channelActive); + void swiftConntrollerButt(); }; #endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui index d25b82b..66d8d47 100644 --- a/PhaseWindow.ui +++ b/PhaseWindow.ui @@ -6,840 +6,1018 @@ 0 0 - 1366 + 1200 720 - 1366 + 1200 0 比相仪测量软件 - - - - 0 - 100 - 100 - 30 - + + + 0 - - - 微软雅黑 - 10 - + + 1 - - QFrame::NoFrame + + 1 - - Qt::ScrollBarAlwaysOff + + 1 - - true + + 1 - - - - 0 - 0 - 100 - 30 - - - - - - - - 1300 - 10 - 40 - 40 - - - - - - - 退出 - - - - - - 0 - 0 - 200 - 50 - - - - - 微软雅黑 - 16 - - - - 比相仪测量软件 - - - Qt::AlignCenter - - - - - - 0 - 90 - 1371 - 16 - - - - QFrame::Plain - - - Qt::Horizontal - - - - - - 1250 - 10 - 40 - 40 - - - - - - - 最小化 - - - - - - 1200 - 10 - 40 - 40 - - - - - - - 配置 - - - - - - 0 - 50 - 240 - 40 - - - - - 微软雅黑 - 12 - 75 - true - - - - Qt::RightToLeft - - - 2021-12-10 10:00:00 - - - Qt::AlignCenter - - - - - - 230 - 35 - 941 - 40 - - - - - 1 - - - - - + + + + + 0 + 0 + + + + + 5 - - :/points/images/green.png + + 20 - - Qt::AlignCenter + + 0 + + + 0 + + + 0 + + + + + + + + Qt::AlignCenter + + + + + + + 0 + + + 10 + + + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + + + + 0 + + + 40 + + + + + + 705 + 0 + + + + + 780 + 30 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + 705 + 0 + + + + + 780 + 40 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 开始测量 + + + + :/images/start.png:/images/start.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 停止测量 + + + + :/images/stop.png:/images/stop.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 系统设置 + + + + :/images/config.png:/images/config.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + 0 + + + 0 + + + 10 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 关闭 + + + + + + + + + + Qt::Vertical + + + + 60 + 37 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 最小化 + + + + + + + + + + + + + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 1198 + 651 + - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - 230 - 65 - 941 - 30 - - - - - 0 - - - 0 - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 1 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 2 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 3 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 4 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 5 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 6 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 7 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 8 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 9 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 10 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 11 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 12 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 13 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 14 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 15 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 16 - - - Qt::AlignCenter - - - - - - - - - 1100 - 10 - 40 - 40 - - - - - - - 开始 - - - - - - 1150 - 10 - 40 - 40 - - - - - - - 结束 - - + + + diff --git a/images.qrc b/images.qrc index 0fc1f3e..08fb3f8 100644 --- a/images.qrc +++ b/images.qrc @@ -3,4 +3,18 @@ images/white.png images/green.png + + images/fontawesome-webfont.ttf + images/main_config.png + images/phaseMeasure.png + images/config.png + images/start.png + images/stop.png + images/chart.png + images/clear.png + + + images/add_bottom.png + images/add_top.png + diff --git a/images/add_bottom.png b/images/add_bottom.png new file mode 100644 index 0000000..2f8c0f2 --- /dev/null +++ b/images/add_bottom.png Binary files differ diff --git a/images/add_top.png b/images/add_top.png new file mode 100644 index 0000000..a5ceb4f --- /dev/null +++ b/images/add_top.png Binary files differ diff --git a/images/chart.png b/images/chart.png new file mode 100644 index 0000000..e7871bd --- /dev/null +++ b/images/chart.png Binary files differ diff --git a/images/clear.png b/images/clear.png new file mode 100644 index 0000000..b825e6d --- /dev/null +++ b/images/clear.png Binary files differ diff --git a/images/config.png b/images/config.png new file mode 100644 index 0000000..55aaccc --- /dev/null +++ b/images/config.png Binary files differ diff --git a/images/fontawesome-webfont.ttf b/images/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 --- /dev/null +++ b/images/fontawesome-webfont.ttf Binary files differ diff --git a/images/green.png b/images/green.png index a33ee4b..369e54f 100644 --- a/images/green.png +++ b/images/green.png Binary files differ diff --git a/images/main_config.png b/images/main_config.png new file mode 100644 index 0000000..d45b094 --- /dev/null +++ b/images/main_config.png Binary files differ diff --git a/images/phaseMeasure.png b/images/phaseMeasure.png new file mode 100644 index 0000000..184237b --- /dev/null +++ b/images/phaseMeasure.png Binary files differ diff --git a/images/start.png b/images/start.png new file mode 100644 index 0000000..725c304 --- /dev/null +++ b/images/start.png Binary files differ diff --git a/images/stop.png b/images/stop.png new file mode 100644 index 0000000..2742084 --- /dev/null +++ b/images/stop.png Binary files differ diff --git a/images/white.png b/images/white.png index 337df06..dc84601 100644 --- a/images/white.png +++ b/images/white.png Binary files differ diff --git a/main.cpp b/main.cpp index adf5eeb..382d44a 100644 --- a/main.cpp +++ b/main.cpp @@ -1,10 +1,32 @@ #include "PhaseWindow.h" - +#include "AppInit.h" #include +#include +#include int main(int argc, char *argv[]) { QApplication a(argc, argv); + + QTextCodec *codec = QTextCodec::codecForName("utf-8"); + QTextCodec::setCodecForLocale(codec); + + //加载样式表 + QFile file(QApplication::applicationDirPath() + "/qss/pmdark.css"); + if (file.open(QFile::ReadOnly)) { + QString qss = QLatin1String(file.readAll()); + QString paletteColor = qss.mid(20, 7); + qApp->setPalette(QPalette(QColor(paletteColor))); + qApp->setStyleSheet(qss); + file.close(); + } + + QFont font; + font.setFamily("Microsoft Yahei"); + font.setPixelSize(12); + a.setFont(font); + AppInit::Instance()->start(); + PhaseWindow w; w.show(); return a.exec(); diff --git a/qss.qrc b/qss.qrc new file mode 100644 index 0000000..5314585 --- /dev/null +++ b/qss.qrc @@ -0,0 +1,5 @@ + + + qss/psblack.css + + diff --git a/AppInit.cpp b/AppInit.cpp new file mode 100644 index 0000000..a267f77 --- /dev/null +++ b/AppInit.cpp @@ -0,0 +1,58 @@ +#include "appinit.h" +#include "qmutex.h" +#include "qapplication.h" +#include "qevent.h" +#include "qwidget.h" + +AppInit *AppInit::self = 0; +AppInit *AppInit::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new AppInit; + } + } + + return self; +} + +AppInit::AppInit(QObject *parent) : QObject(parent) +{ +} + +bool AppInit::eventFilter(QObject *obj, QEvent *evt) +{ + QWidget *w = (QWidget *)obj; + if (!w->property("canMove").toBool()) { + return QObject::eventFilter(obj, evt); + } + + static QPoint mousePoint; + static bool mousePressed = false; + + QMouseEvent *event = static_cast(evt); + if (event->type() == QEvent::MouseButtonPress) { + if (event->button() == Qt::LeftButton) { + mousePressed = true; + mousePoint = event->globalPos() - w->pos(); + return true; + } + } else if (event->type() == QEvent::MouseButtonRelease) { + mousePressed = false; + return true; + } else if (event->type() == QEvent::MouseMove) { + if (mousePressed && (event->buttons() && Qt::LeftButton)) { + w->move(event->globalPos() - mousePoint); + return true; + } + } + + return QObject::eventFilter(obj, evt); +} + +void AppInit::start() +{ + qApp->installEventFilter(this); +} diff --git a/AppInit.h b/AppInit.h new file mode 100644 index 0000000..6b35009 --- /dev/null +++ b/AppInit.h @@ -0,0 +1,26 @@ +#ifndef APPINIT_H +#define APPINIT_H + +#include + +class AppInit : public QObject +{ + Q_OBJECT +public: + static AppInit *Instance(); + explicit AppInit(QObject *parent = 0); + + void start(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); + +private: + static AppInit *self; + +signals: + +public slots: +}; + +#endif // APPINIT_H diff --git a/ChannelCharts.cpp b/ChannelCharts.cpp index eb58127..954522e 100644 --- a/ChannelCharts.cpp +++ b/ChannelCharts.cpp @@ -11,66 +11,101 @@ ui(new Ui::ChannelCharts) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 } ChannelCharts::~ChannelCharts() { - std::cout << "in destructor" << std::endl; delete ui; } void ChannelCharts::initDataChart(int index) { - ui->dataPlot->addGraph(); // blue line - ui->dataPlot->graph(0)->setPen(QPen(QColor(40, 110, 255))); -// ui->dataPlot->addGraph(); // red line -// ui->dataPlot->graph(1)->setPen(QPen(QColor(255, 110, 40))); + QCPGraph * graph = ui->dataPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + graph->setPen(QPen(QColor("#ff4757"))); - QSharedPointer timeTicker(new QCPAxisTickerTime); - timeTicker->setTimeFormat("%h:%m:%s"); + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer timeTicker(new QCPAxisTickerDateTime); + timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); - ui->dataPlot->axisRect()->setupFullAxesBox(); - ui->dataPlot->yAxis->setRange(1e-9, 1e-8); + ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->dataPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 - qint64 base = phaseVector[index].at(0).at(0).toLongLong(); + ui->dataPlot->xAxis->setLabel("时间"); + ui->dataPlot->yAxis->setLabel("时差测量值"); +/* + // 游标 + QCPItemTracer * tracer = new QCPItemTracer(ui->dataPlot); + tracer->setInterpolating(false); // 禁用插值,游标自动吸附到最近的点 + tracer->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 颜色、宽度、线型 // 标签色(warning) #FAA732 + tracer->setStyle(QCPItemTracer::tsCircle); // 样式:十字星、圆圈、方框等 + tracer->setSize(10.0); - QColor color(20+200,105, 150, 150); - ui->dataPlot->graph()->setLineStyle(QCPGraph::lsLine); - ui->dataPlot->graph()->setPen(QPen(color.lighter(200))); - ui->dataPlot->graph()->setBrush(QBrush(color)); - // generate random walk data: -// QVector timeData(phaseVector[index].size()); - for (int i=0; idataPlot->graph(0)->addData((phaseVector[index].at(i).at(0).toLongLong() - base) / 1000.0, phaseVector[index].at(i).at(1).toDouble()); - } -// ui->dataPlot->graph()->data()->set(timeData); + // 游标数据标签 + QCPItemText * tracerLabel = new QCPItemText(ui->dataPlot); + tracerLabel->setLayer("overlay"); + tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop); + tracerLabel->setTextAlignment(Qt::AlignLeft); + tracerLabel->setPadding(QMargins(5, 5, 5, 5)); // 边界宽度 + tracerLabel->position->setParentAnchor(tracer->position); // 锚固在tracer位置处,实现自动跟随 - // configure bottom axis to show date instead of number: - // configure left axis text labels: - // set a more compact font size for bottom and left axis tick labels: - ui->dataPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8)); - ui->dataPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8)); - // set axis labels: - ui->dataPlot->xAxis->setLabel("Date"); - ui->dataPlot->yAxis->setLabel("Random wobbly lines value"); - // make top and right axes visible but without ticks and labels: - ui->dataPlot->xAxis2->setVisible(true); - ui->dataPlot->yAxis2->setVisible(true); - ui->dataPlot->xAxis2->setTicks(false); - ui->dataPlot->yAxis2->setTicks(false); - ui->dataPlot->xAxis2->setTickLabels(false); - ui->dataPlot->yAxis2->setTickLabels(false); - // set axis ranges to show all data: - ui->dataPlot->xAxis->setRange((phaseVector[index].at(0).at(0).toULongLong() - base) / 1000.0, (phaseVector[index].last().at(0).toULongLong() - base) / 1000.0); - // show legend with slightly transparent background brush: + // 游标垂直线 + QCPItemStraightLine * tracerLineV = new QCPItemStraightLine(ui->dataPlot); + tracerLineV->setLayer("overlay"); + tracerLineV->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineV->setClipToAxisRect(true); + tracerLineV->point1->setCoords(0, 0); + tracerLineV->point2->setCoords(0, 0); + + // 游标水平线 + QCPItemStraightLine * tracerLineH = new QCPItemStraightLine(ui->dataPlot); + tracerLineH->setLayer("overlay"); + tracerLineH->setPen(QPen(QColor("#FAA732"), 1, Qt::DashLine)); // 标签色(warning) #FAA732 + tracerLineH->setClipToAxisRect(true); + tracerLineH->point1->setCoords(0, 0); + tracerLineH->point2->setCoords(0, 0); +*/ + double minTm = phaseVector[index].first().at(0).toLongLong() / 1000; + double maxTm = phaseVector[index].last().at(0).toLongLong() / 1000; + double minValue = phaseVector[index].first().at(1).toDouble(); + double maxValue = phaseVector[index].first().at(1).toDouble(); + QVector vecPoints; + + for (int i = 0; i < phaseVector[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + QDateTime dtime = QDateTime::fromSecsSinceEpoch(phaseVector[index].at(i).at(0).toLongLong() / 1000); // 日期时间 + onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); + onePoint.value = phaseVector[index].at(i).at(1).toDouble(); + + vecPoints.append(onePoint); + + if (phaseVector[index].at(i).at(1).toDouble() < minValue) + { + minValue = phaseVector[index][i].at(1).toDouble(); + } + + if (phaseVector[index].at(i).at(1).toDouble() > maxValue) + { + maxValue = phaseVector[index][i].at(1).toDouble(); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->dataPlot->xAxis->setRange(minTm, maxTm); + ui->dataPlot->yAxis->setRange(minValue, maxValue); + ui->dataPlot->legend->setVisible(false); - ui->dataPlot->legend->setBrush(QColor(255, 255, 255, 150)); - ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +// ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } void ChannelCharts::initAllenChart(int index) { + /* QLinearGradient gradient(0, 0, 0, 400); gradient.setColorAt(0, QColor(90, 90, 90)); gradient.setColorAt(0.38, QColor(105, 105, 105)); @@ -144,4 +179,80 @@ // legendFont.setPointSize(10); // ui->allenPlot->legend->setFont(legendFont); ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + */ + + QCPGraph * graph = ui->allenPlot->addGraph(); + graph->setName("时差(ns)"); + graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) + QPen pen; + pen.setColor(QColor(0, 168, 140)); + pen.setWidth(3);//线宽 + graph->setPen(pen); + + QLinearGradient gradient(0, 0, 0, 400); + gradient.setColorAt(0, QColor(90, 90, 90)); + gradient.setColorAt(0.38, QColor(105, 105, 105)); + gradient.setColorAt(1, QColor(70, 70, 70)); + ui->allenPlot->setBackground(QBrush(gradient)); + + ui->allenPlot->xAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->xAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->xAxis->setPadding(5); + ui->allenPlot->xAxis->grid()->setVisible(true); + ui->allenPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + ui->allenPlot->xAxis->setTickLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabelColor(Qt::white); + ui->allenPlot->xAxis->setLabel("平均时间(秒)"); + + ui->allenPlot->yAxis->setPadding(5); // a bit more space to the left border + ui->allenPlot->yAxis->setLabel("阿伦方差"); + ui->allenPlot->yAxis->setBasePen(QPen(Qt::white)); + ui->allenPlot->yAxis->setTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->setSubTickPen(QPen(Qt::white)); + ui->allenPlot->yAxis->grid()->setSubGridVisible(true); + ui->allenPlot->yAxis->setTickLabelColor(Qt::white); + ui->allenPlot->yAxis->setLabelColor(Qt::white); + ui->allenPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); + ui->allenPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); + + + // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). + QSharedPointer logTicker(new QCPAxisTickerLog); + ui->allenPlot->xAxis->setTicker(logTicker); + ui->allenPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× + ui->allenPlot->yAxis->setNumberPrecision(4); // Y 轴:精度,有效数字的位数 + ui->allenPlot->xAxis->setScaleType(QCPAxis::stLogarithmic); + + channelAllan[index] = {2.48e-13, 1.11e-13, 2.6e-14, 5.26e-15, 1.28e-15}; + + double minValue = channelAllan[index].first(); + double maxValue = channelAllan[index].first(); + QVector vecPoints; + + for (int i = 0; i < channelAllan[index].size(); i++) + { + // 新的数据点 + QCPGraphData onePoint; + + onePoint.key = pow(10, i); + onePoint.value = channelAllan[index].at(i); + vecPoints.append(onePoint); + + if (channelAllan[index].at(i) < minValue) + { + minValue = channelAllan[index].at(i); + } + + if (channelAllan[index].at(i) > maxValue) + { + maxValue = channelAllan[index].at(i); + } + } + graph->data()->clear(); + graph->data()->set(vecPoints, true); + ui->allenPlot->xAxis->setRange(1, 11000); + ui->allenPlot->yAxis->setRange(minValue, maxValue); + + ui->allenPlot->legend->setVisible(false); + ui->allenPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); } diff --git a/ChannelItem.cpp b/ChannelItem.cpp index a000598..f94ee11 100644 --- a/ChannelItem.cpp +++ b/ChannelItem.cpp @@ -12,10 +12,6 @@ QFont font("微软雅黑"); font.setPixelSize(16); ui->delay->setFont(font); - - chartFrame = new ChannelCharts(); - chartFrame->setWindowModality(Qt::ApplicationModal); - chartFrame->hide(); } ChannelItem::~ChannelItem() @@ -79,6 +75,8 @@ void ChannelItem::on_chartViewButt_clicked() { + ChannelCharts * chartFrame = new ChannelCharts(); + chartFrame->setWindowModality(Qt::ApplicationModal); chartFrame->setWindowTitle(QString("通道 - %1 数据曲线").arg(index + 1)); chartFrame->initAllenChart(index); chartFrame->initDataChart(index); diff --git a/ChannelItem.h b/ChannelItem.h index 6198147..b6cbad5 100644 --- a/ChannelItem.h +++ b/ChannelItem.h @@ -33,7 +33,6 @@ private: Ui::ChannelItem *ui; - ChannelCharts * chartFrame; int index; double channelDelay = 0.0; }; diff --git a/ChannelItem.ui b/ChannelItem.ui index ef827f5..13e7b17 100644 --- a/ChannelItem.ui +++ b/ChannelItem.ui @@ -416,7 +416,7 @@ 1160 30 - 101 + 40 35 @@ -428,16 +428,29 @@ false + + background:none; + - 查看曲线 + + + + + :/images/chart.png:/images/chart.png + + + + 32 + 32 + - 1160 - 70 - 101 + 1210 + 30 + 40 35 @@ -450,7 +463,17 @@ - 清除数据 + + + + + :/images/clear.png:/images/clear.png + + + + 32 + 32 + @@ -706,6 +729,8 @@ - + + + diff --git a/IconHelper.cpp b/IconHelper.cpp new file mode 100644 index 0000000..e548117 --- /dev/null +++ b/IconHelper.cpp @@ -0,0 +1,233 @@ +#include "iconhelper.h" + +IconHelper *IconHelper::self = 0; +IconHelper *IconHelper::Instance() +{ + if (!self) { + QMutex mutex; + QMutexLocker locker(&mutex); + if (!self) { + self = new IconHelper; + } + } + + return self; +} + +IconHelper::IconHelper(QObject *) : QObject(qApp) +{ + int fontId = QFontDatabase::addApplicationFont(":/images/fontawesome-webfont.ttf"); + QStringList fontName = QFontDatabase::applicationFontFamilies(fontId); + + if (fontName.count() > 0) { + iconFont = QFont(fontName.at(0)); + } else { + qDebug() << "load fontawesome-webfont.ttf error"; + } +} + +void IconHelper::setIcon(QLabel *lab, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + lab->setFont(iconFont); + lab->setText(c); +} + +void IconHelper::setIcon(QAbstractButton *btn, QChar c, quint32 size) +{ + iconFont.setPixelSize(size); + btn->setFont(iconFont); + btn->setText(c); +} + +QPixmap IconHelper::getPixmap(const QString &color, QChar c, quint32 size, + quint32 pixWidth, quint32 pixHeight) +{ + QPixmap pix(pixWidth, pixHeight); + pix.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pix); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + painter.setPen(QColor(color)); + painter.setBrush(QColor(color)); + + iconFont.setPixelSize(size); + painter.setFont(iconFont); + painter.drawText(pix.rect(), Qt::AlignCenter, c); + painter.end(); + + return pix; +} + +QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal) +{ + QPixmap pix; + int index = btns.indexOf(btn); + + if (index >= 0) { + if (normal) { + pix = pixNormal.at(index); + } else { + pix = pixDark.at(index); + } + } + + return pix; +} + +void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + QStringList qss; + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + widget->setStyleSheet(qss.join("")); +} + +void IconHelper::setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &type, int borderWidth, const QString &borderColor, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QString strBorder; + if (type == "top") { + strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "right") { + strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "bottom") { + strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;") + .arg(borderWidth).arg(borderWidth * 2); + } else if (type == "left") { + strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;") + .arg(borderWidth).arg(borderWidth * 2); + } + + //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色 + QStringList qss; + if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor)); + } else { + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}") + .arg(type).arg(normalTextColor).arg(normalBgColor)); + } + + qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover," + "QWidget[flag=\"%1\"] QAbstractButton:pressed," + "QWidget[flag=\"%1\"] QAbstractButton:checked{" + "border-style:solid;%2border-color:%3;color:%4;background:%5;}") + .arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor)); + + qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor)); + + qss.append(QString("QWidget>QToolButton{border-width:0px;}")); + qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + widget->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +void IconHelper::setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize, quint32 iconWidth, quint32 iconHeight, + const QString &normalBgColor, const QString &darkBgColor, + const QString &normalTextColor, const QString &darkTextColor) +{ + int btnCount = btns.count(); + int charCount = pixChar.count(); + if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) { + return; + } + + QStringList qss; + qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}")); + qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}") + .arg(normalBgColor).arg(normalTextColor)); + qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}") + .arg(darkBgColor).arg(darkTextColor)); + + frame->setStyleSheet(qss.join("")); + + for (int i = 0; i < btnCount; i++) { + //存储对应按钮对象,方便鼠标移上去的时候切换图片 + QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight); + + btns.at(i)->setIcon(QIcon(pixNormal)); + btns.at(i)->setIconSize(QSize(iconWidth, iconHeight)); + btns.at(i)->installEventFilter(this); + + this->btns.append(btns.at(i)); + this->pixNormal.append(pixNormal); + this->pixDark.append(pixDark); + } +} + +bool IconHelper::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->inherits("QToolButton")) { + QToolButton *btn = (QToolButton *)watched; + int index = btns.indexOf(btn); + if (index >= 0) { + if (event->type() == QEvent::Enter) { + btn->setIcon(QIcon(pixDark.at(index))); + } else if (event->type() == QEvent::Leave) { + if (btn->isChecked()) { + btn->setIcon(QIcon(pixDark.at(index))); + } else { + btn->setIcon(QIcon(pixNormal.at(index))); + } + } + } + } + + return QObject::eventFilter(watched, event); +} diff --git a/IconHelper.h b/IconHelper.h new file mode 100644 index 0000000..39ba363 --- /dev/null +++ b/IconHelper.h @@ -0,0 +1,63 @@ +#ifndef ICONHELPER_H +#define ICONHELPER_H + +#include +#include +#if (QT_VERSION > QT_VERSION_CHECK(5,0,0)) +#include +#endif + +//图形字体处理类 +class IconHelper : public QObject +{ + Q_OBJECT + +public: + static IconHelper *Instance(); + explicit IconHelper(QObject *parent = 0); + + void setIcon(QLabel *lab, QChar c, quint32 size = 12); + void setIcon(QAbstractButton *btn, QChar c, quint32 size = 12); + QPixmap getPixmap(const QString &color, QChar c, quint32 size = 12, + quint32 pixWidth = 10, quint32 pixHeight = 10); + + //根据按钮获取该按钮对应的图标 + QPixmap getPixmap(QToolButton *btn, bool normal); + + //指定导航面板样式,不带图标 + static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航面板样式,带图标和效果切换 + void setStyle(QWidget *widget, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &type = "left", int borderWidth = 3, + const QString &borderColor = "#029FEA", + const QString &normalBgColor = "#292F38", + const QString &darkBgColor = "#1D2025", + const QString &normalTextColor = "#54626F", + const QString &darkTextColor = "#FDFDFD"); + + //指定导航按钮样式,带图标和效果切换 + void setStyle(QFrame *frame, QList btns, QList pixChar, + quint32 iconSize = 9, quint32 iconWidth = 10, quint32 iconHeight = 10, + const QString &normalBgColor = "#2FC5A2", + const QString &darkBgColor = "#3EA7E9", + const QString &normalTextColor = "#EEEEEE", + const QString &darkTextColor = "#FFFFFF"); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + static IconHelper *self; //对象自身 + QFont iconFont; //图形字体 + QList btns; //按钮队列 + QList pixNormal; //正常图片队列 + QList pixDark; //加深图片队列 +}; +#endif // ICONHELPER_H diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp index d39544c..4b7da04 100644 --- a/PhaseDevice.cpp +++ b/PhaseDevice.cpp @@ -18,10 +18,12 @@ connect(clientUtil, &UDPClientUtil::dataRecieved, this, &PhaseDevice::dataReceivedHandler); -// QTimer * timer = new QTimer(this); -// connect(timer, &QTimer::timeout, -// this, &PhaseDevice::mockPhaseData); -// timer->start(1000); + base = (qrand() % 100000) * 1000; + + QTimer * timer = new QTimer(this); + connect(timer, &QTimer::timeout, + this, &PhaseDevice::mockPhaseData); + timer->start(1000); } PhaseDevice::~PhaseDevice() @@ -151,7 +153,7 @@ for (int i = 1; i <= 16; i++) { - int value = qrand() % 10000; + int value = base + qrand() % 40; buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); } diff --git a/PhaseDevice.h b/PhaseDevice.h index 11c88eb..683077d 100644 --- a/PhaseDevice.h +++ b/PhaseDevice.h @@ -24,6 +24,7 @@ QByteArray dataBuff; void mockPhaseData(); + qlonglong base; signals: void sendDataToDraw(PhaseDataDto * phaseData); diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro index 52698ab..8f6a23d 100644 --- a/PhaseMeasure.pro +++ b/PhaseMeasure.pro @@ -13,6 +13,8 @@ include(protocol/protocol.pri) include(QCustomPlot/QCustomPlot.pri) +HEADERS += AppInit.h +HEADERS += IconHelper.h HEADERS += PhaseDevice.h HEADERS += ChannelCharts.h HEADERS += ChannelItem.h @@ -20,6 +22,8 @@ HEADERS += SetConfig.h HEADERS += DataProcessAlgorithm.h +SOURCES += AppInit.cpp +SOURCES += IconHelper.cpp SOURCES += PhaseDevice.cpp SOURCES += ChannelCharts.cpp SOURCES += ChannelItem.cpp @@ -34,5 +38,7 @@ !isEmpty(target.path): INSTALLS += target DISTFILES += conf/config.ini +DISTFILES += qss/pmdark.css RESOURCES += images.qrc +RC_ICONS = PhaseMeasure.ico diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp index 0c4fb7e..b8e48ef 100644 --- a/PhaseWindow.cpp +++ b/PhaseWindow.cpp @@ -14,10 +14,15 @@ #include #include #include + +#include "IconHelper.h" #include "common/utils/SettingConfig.h" #include "common/utils/QLogUtil.h" QString currentFileName = ""; +qint16 screenWidth = 0; +qint16 screenHeight = 0; +boolean running = false; PhaseWindow::PhaseWindow(QWidget *parent) : QWidget(parent), @@ -25,35 +30,13 @@ { ui->setupUi(this); - // 无边框 - this->setWindowFlags(Qt::FramelessWindowHint); + QRect screenRect = QApplication::desktop()->availableGeometry(); + screenWidth = screenRect.width(); + screenHeight = screenRect.height(); - // 窗口大小为占满一屏 - QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), screenRect.height()); - - // 将窗口移动到左上角 - move(0, 0); - ui->exitButt->move(screenRect.width() - 80, 10); - ui->minButt->move(screenRect.width() - 140, 10); - ui->settingButt->move(screenRect.width() - 200, 10); - ui->endButt->move(screenRect.width() - 260, 10); - ui->startButt->move(screenRect.width() - 320, 10); - ui->line->setGeometry(0, 89, screenRect.width(), 1); - ui->pointsList->setGeometry(250,20,screenRect.width()-600,40); - ui->labelsList->setGeometry(250,50,screenRect.width()-600,30); - - // 设置主体区域的大小和位置 - ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); - ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - ui->tim3->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - + this->initForm(); + this->initDeivce(); this->generateWidgetForDevice(); - - device = new PhaseDevice(this); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); } PhaseWindow::~PhaseWindow() @@ -61,9 +44,78 @@ delete ui; } +void PhaseWindow::initForm() +{ + this->setProperty("form", true); + this->setProperty("canMove", false); + ui->widgetTitle->setProperty("form", "title"); + ui->widgetTop->setProperty("nav", "top"); + this->setWindowFlags(Qt::FramelessWindowHint); + + // 设置窗口位置和大小 + move(0, 0); + resize(screenWidth, screenHeight); + + // 设置最小和关闭按钮的样式 + IconHelper::Instance()->setIcon(ui->btnMenuMin, QChar(0xf068)); + IconHelper::Instance()->setIcon(ui->btnMenuClose, QChar(0xf00d)); + + // 设置标题字体和文字 + QFont titleFont("Microsoft Yahei"); + titleFont.setBold(true); + titleFont.setPixelSize(24); + ui->labTitle->setText("比相仪测量软件"); + ui->labTitle->setFont(titleFont); + this->setWindowTitle(ui->labTitle->text()); + + // 设置时间字体和文字 + QFont tmFont("Arial"); + tmFont.setPixelSize(16); + tmFont.setBold(true); + ui->labTm->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); + ui->labTm->setFont(tmFont); + + // 设置标题logo + QPixmap img(":/images/phaseMeasure.png"); + QPixmap logoImg = img.scaled(42, 42); + ui->labIco->setPixmap(logoImg); + + // 设置通道文字的字体 + QFont chLabelFont("Arial"); + chLabelFont.setPixelSize(14); + chLabelFont.setBold(true); + QList chLabs = ui->labelsList->findChildren(); + foreach (QLabel * chLabel, chLabs) { + chLabel->setFont(chLabelFont); + } + + //设置顶部导航按钮 + QSize icoSize(32, 32); + int icoWidth = 85; + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + btn->setIconSize(icoSize); + btn->setMinimumWidth(icoWidth); + btn->setCheckable(true); + connect(btn, SIGNAL(clicked()), this, SLOT(buttonClick())); + } + ui->endButt->setVisible(running); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenWidth, screenHeight - 70); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void PhaseWindow::initDeivce() +{ + device = new PhaseDevice(this); + connect(device, &PhaseDevice::sendDataToDraw, + this, &PhaseWindow::drawPhaseDataOnPage); +} + void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) { - ui->tim3->setText(phaseData->timestamp.left(19)); + ui->labTm->setText(phaseData->timestamp.left(19)); updateChannelActive(phaseData->channelActive); // 更新所有通道BOX的值 @@ -94,7 +146,7 @@ { // 通道状态图标默认显示为离线/无效状态 QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); + label->setPixmap(QPixmap(":/points/images/green.png")); QGroupBox * group = new QGroupBox(ui->scrollContents); group->setTitle(QString("通道 - %1").arg(i + 1)); @@ -114,49 +166,6 @@ } } -void PhaseWindow::updateChannelActive(QList channelActive) -{ - for (int i = 0; i < channelActive.size(); i++) - { - if (channelActive.at(i) == "1") - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/green.png")); - - // 显示有效的通道 - this->channelGroupList.at(i)->show(); - } else - { - QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 - label->setPixmap(QPixmap(":/points/images/white.png")); - - // 隐藏无效的通道 - this->channelGroupList.at(i)->hide(); - } - } -} - - -void PhaseWindow::on_minButt_clicked() -{ - setWindowState(Qt::WindowMinimized | windowState()); -} - -void PhaseWindow::on_exitButt_clicked() -{ - // 发送结束指令 - device->stopWork(); - - QTimer::singleShot(500, qApp, SLOT(quit())); -} - -void PhaseWindow::on_startButt_clicked() -{ - //发送开始指令 - device->startWork(); - createFolder(); -} - void PhaseWindow::createFolder() { QDir *folder = new QDir; @@ -179,9 +188,79 @@ } } + +void PhaseWindow::updateChannelActive(QList channelActive) +{ + for (int i = 0; i < channelActive.size(); i++) + { + if (channelActive.at(i) == "1") + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/green.png")); + + // 显示有效的通道 + this->channelGroupList.at(i)->show(); + } else + { + QLabel* label = ui->pointsList->findChild(QString("p%1").arg(i+1)); //根据子控件的名称查找子控件 + label->setPixmap(QPixmap(":/points/images/white.png")); + + // 隐藏无效的通道 + this->channelGroupList.at(i)->hide(); + } + } +} + +void PhaseWindow::swiftConntrollerButt() +{ + ui->startButt->setVisible(!running); + ui->endButt->setVisible(running); +} + +void PhaseWindow::on_btnMenuMin_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} +void PhaseWindow::on_btnMenuClose_clicked() +{ + // 发送结束指令 + device->stopWork(); + + QTimer::singleShot(500, qApp, SLOT(quit())); +} + +void PhaseWindow::buttonClick() +{ + QToolButton *b = (QToolButton *)sender(); + QString name = b->text(); + + QList tbtns = ui->widgetTop->findChildren(); + foreach (QToolButton *btn, tbtns) { + if (btn == b) { + btn->setChecked(true); + } else { + btn->setChecked(false); + } + } + + // 如果是开始或者结束测量按钮被点击则切换显示按钮 + if (name.contains("开始") || name.contains("停止") || name.contains("测量")) { + swiftConntrollerButt(); + } +} + +void PhaseWindow::on_startButt_clicked() +{ + // 发送开始指令 + device->startWork(); + createFolder(); + running = true; +} + void PhaseWindow::on_endButt_clicked() { currentFileName = ""; + // 清空已经存储的数据 for (int i = 0; i < phaseVector.size(); i++) { @@ -190,6 +269,7 @@ // 发送结束指令 device->stopWork(); + running = false; } void PhaseWindow::on_settingButt_clicked() diff --git a/PhaseWindow.h b/PhaseWindow.h index bfb44b6..6fc532c 100644 --- a/PhaseWindow.h +++ b/PhaseWindow.h @@ -25,13 +25,14 @@ void drawPhaseDataOnPage(PhaseDataDto * phaseData); private slots: - void on_minButt_clicked(); - void on_exitButt_clicked(); - void on_startButt_clicked(); void on_endButt_clicked(); void on_settingButt_clicked(); + void buttonClick(); + void on_btnMenuMin_clicked(); + void on_btnMenuClose_clicked(); + private: Ui::PhaseWindow *ui; QList channelGroupList; @@ -39,10 +40,12 @@ PhaseDevice * device; - + void initForm(); + void initDeivce(); void createFolder(); void generateWidgetForDevice(); void updateChannelActive(QList channelActive); + void swiftConntrollerButt(); }; #endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui index d25b82b..66d8d47 100644 --- a/PhaseWindow.ui +++ b/PhaseWindow.ui @@ -6,840 +6,1018 @@ 0 0 - 1366 + 1200 720 - 1366 + 1200 0 比相仪测量软件 - - - - 0 - 100 - 100 - 30 - + + + 0 - - - 微软雅黑 - 10 - + + 1 - - QFrame::NoFrame + + 1 - - Qt::ScrollBarAlwaysOff + + 1 - - true + + 1 - - - - 0 - 0 - 100 - 30 - - - - - - - - 1300 - 10 - 40 - 40 - - - - - - - 退出 - - - - - - 0 - 0 - 200 - 50 - - - - - 微软雅黑 - 16 - - - - 比相仪测量软件 - - - Qt::AlignCenter - - - - - - 0 - 90 - 1371 - 16 - - - - QFrame::Plain - - - Qt::Horizontal - - - - - - 1250 - 10 - 40 - 40 - - - - - - - 最小化 - - - - - - 1200 - 10 - 40 - 40 - - - - - - - 配置 - - - - - - 0 - 50 - 240 - 40 - - - - - 微软雅黑 - 12 - 75 - true - - - - Qt::RightToLeft - - - 2021-12-10 10:00:00 - - - Qt::AlignCenter - - - - - - 230 - 35 - 941 - 40 - - - - - 1 - - - - - + + + + + 0 + 0 + + + + + 5 - - :/points/images/green.png + + 20 - - Qt::AlignCenter + + 0 + + + 0 + + + 0 + + + + + + + + Qt::AlignCenter + + + + + + + 0 + + + 10 + + + + + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + + + + 0 + + + 40 + + + + + + 705 + 0 + + + + + 780 + 30 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + 705 + 0 + + + + + 780 + 40 + + + + + 10 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 开始测量 + + + + :/images/start.png:/images/start.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 停止测量 + + + + :/images/stop.png:/images/stop.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + 0 + 0 + + + + 系统设置 + + + + :/images/config.png:/images/config.png + + + Qt::ToolButtonTextUnderIcon + + + + + + + + + + + 0 + + + 0 + + + 10 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 关闭 + + + + + + + + + + Qt::Vertical + + + + 60 + 37 + + + + + + + + + 0 + 0 + + + + + 30 + 30 + + + + + 30 + 30 + + + + ArrowCursor + + + Qt::NoFocus + + + 最小化 + + + + + + + + + + + + + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 1198 + 651 + - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/white.png - - - Qt::AlignCenter - - - - - - - - - - :/points/images/green.png - - - Qt::AlignCenter - - - - - - - - - 230 - 65 - 941 - 30 - - - - - 0 - - - 0 - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 1 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 2 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 3 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 4 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 5 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 6 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 7 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 8 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 9 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 10 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 11 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 12 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 13 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 14 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 15 - - - Qt::AlignCenter - - - - - - - - 0 - 30 - - - - - 微软雅黑 - 10 - - - - Qt::LeftToRight - - - 16 - - - Qt::AlignCenter - - - - - - - - - 1100 - 10 - 40 - 40 - - - - - - - 开始 - - - - - - 1150 - 10 - 40 - 40 - - - - - - - 结束 - - + + + diff --git a/images.qrc b/images.qrc index 0fc1f3e..08fb3f8 100644 --- a/images.qrc +++ b/images.qrc @@ -3,4 +3,18 @@ images/white.png images/green.png + + images/fontawesome-webfont.ttf + images/main_config.png + images/phaseMeasure.png + images/config.png + images/start.png + images/stop.png + images/chart.png + images/clear.png + + + images/add_bottom.png + images/add_top.png + diff --git a/images/add_bottom.png b/images/add_bottom.png new file mode 100644 index 0000000..2f8c0f2 --- /dev/null +++ b/images/add_bottom.png Binary files differ diff --git a/images/add_top.png b/images/add_top.png new file mode 100644 index 0000000..a5ceb4f --- /dev/null +++ b/images/add_top.png Binary files differ diff --git a/images/chart.png b/images/chart.png new file mode 100644 index 0000000..e7871bd --- /dev/null +++ b/images/chart.png Binary files differ diff --git a/images/clear.png b/images/clear.png new file mode 100644 index 0000000..b825e6d --- /dev/null +++ b/images/clear.png Binary files differ diff --git a/images/config.png b/images/config.png new file mode 100644 index 0000000..55aaccc --- /dev/null +++ b/images/config.png Binary files differ diff --git a/images/fontawesome-webfont.ttf b/images/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 --- /dev/null +++ b/images/fontawesome-webfont.ttf Binary files differ diff --git a/images/green.png b/images/green.png index a33ee4b..369e54f 100644 --- a/images/green.png +++ b/images/green.png Binary files differ diff --git a/images/main_config.png b/images/main_config.png new file mode 100644 index 0000000..d45b094 --- /dev/null +++ b/images/main_config.png Binary files differ diff --git a/images/phaseMeasure.png b/images/phaseMeasure.png new file mode 100644 index 0000000..184237b --- /dev/null +++ b/images/phaseMeasure.png Binary files differ diff --git a/images/start.png b/images/start.png new file mode 100644 index 0000000..725c304 --- /dev/null +++ b/images/start.png Binary files differ diff --git a/images/stop.png b/images/stop.png new file mode 100644 index 0000000..2742084 --- /dev/null +++ b/images/stop.png Binary files differ diff --git a/images/white.png b/images/white.png index 337df06..dc84601 100644 --- a/images/white.png +++ b/images/white.png Binary files differ diff --git a/main.cpp b/main.cpp index adf5eeb..382d44a 100644 --- a/main.cpp +++ b/main.cpp @@ -1,10 +1,32 @@ #include "PhaseWindow.h" - +#include "AppInit.h" #include +#include +#include int main(int argc, char *argv[]) { QApplication a(argc, argv); + + QTextCodec *codec = QTextCodec::codecForName("utf-8"); + QTextCodec::setCodecForLocale(codec); + + //加载样式表 + QFile file(QApplication::applicationDirPath() + "/qss/pmdark.css"); + if (file.open(QFile::ReadOnly)) { + QString qss = QLatin1String(file.readAll()); + QString paletteColor = qss.mid(20, 7); + qApp->setPalette(QPalette(QColor(paletteColor))); + qApp->setStyleSheet(qss); + file.close(); + } + + QFont font; + font.setFamily("Microsoft Yahei"); + font.setPixelSize(12); + a.setFont(font); + AppInit::Instance()->start(); + PhaseWindow w; w.show(); return a.exec(); diff --git a/qss.qrc b/qss.qrc new file mode 100644 index 0000000..5314585 --- /dev/null +++ b/qss.qrc @@ -0,0 +1,5 @@ + + + qss/psblack.css + + diff --git a/qss/pmdark.css b/qss/pmdark.css new file mode 100644 index 0000000..eb75d5b --- /dev/null +++ b/qss/pmdark.css @@ -0,0 +1,104 @@ +QPalette{background:#444444;}*{outline:0px;color:#DCDCDC;} + +QWidget[form="true"] { + background: #444444; + border:1px solid #242424; + border-radius:0px; +} + +QWidget[form="title"] QLabel{ + border-radius:0px; + color:#DCDCDC; + background:none; + border-style:none; +} + +QWidget[form="title"],QWidget[nav="left"],QWidget[nav="top"] QAbstractButton{ + border-style:none; + border-radius:0px; + padding:5px; + color:#DCDCDC; + background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #484848,stop:1 #383838); +} + +QWidget[nav="top"] QAbstractButton:hover,QWidget[nav="top"] QAbstractButton:pressed,QWidget[nav="top"] QAbstractButton:checked{ + border-style:solid; + border-width:0px 0px 2px 0px; + padding:4px 4px 2px 4px; + border-color:#00BB9E; + background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #646464,stop:1 #525252); +} + +QPushButton#btnMenuMin,QPushButton#btnMenuClose{ + border-radius:3px; + color:#DCDCDC; + padding:3px; + margin:0px; + background:none; + border-style:none; +} + +QPushButton#btnMenuMin:hover{ + color:#FFFFFF; + margin:1px 1px 2px 1px; + background-color:rgba(51,127,209,230); +} + +QPushButton#btnMenuClose:hover{ + color:#FFFFFF; + margin:1px 1px 2px 1px; + background-color:rgba(238,0,0,128); +} + + +QScrollBar:vertical +{ + width:8px; + background:rgba(0,0,0,0%); + margin:0px,0px,0px,0px; + padding-top:12px; + padding-bottom:12px; +} +QScrollBar::handle:vertical +{ + width:8px; + background:rgba(0,0,0,25%); + border-radius:4px; + min-height:20; +} +QScrollBar::handle:vertical:hover +{ + width:8px; + background:rgba(0,0,0,50%); + border-radius:4px; + min-height:20; +} +QScrollBar::add-line:vertical +{ + height:12px;width:12px; + border-image:url(:/css/images/add_bottom.png); + subcontrol-position:bottom; +} +QScrollBar::sub-line:vertical +{ + height:12px;width:12px; + border-image:url(:/css/images/add_top.png); + subcontrol-position:top; +} +QScrollBar::add-line:vertical:hover +{ + height:12px;width:12px; + border-image:url(:/css/images/add_bottom.png); + subcontrol-position:bottom; +} +QScrollBar::sub-line:vertical:hover +{ + height:12px;width:12px; + border-image:url(:/css/images/add_top.png); + subcontrol-position:top; +} +QScrollBar::add-page:vertical,QScrollBar::sub-page:vertical +{ + background:rgba(0,0,0,10%); + border-radius:4px; +}