添加项目文件。

This commit is contained in:
keyeslll 2023-01-16 15:10:44 +08:00
parent 1d2c142e68
commit a2c503fd15
12 changed files with 43723 additions and 0 deletions

22
realTimeDataDisplay.sln Normal file
View File

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.33027.164
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "realTimeDataDisplay", "realTimeDataDisplay\realTimeDataDisplay.vcxproj", "{84C0F098-0883-4B60-88A7-3F1DE62EF226}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{84C0F098-0883-4B60-88A7-3F1DE62EF226}.Release|x64.ActiveCfg = Release|x64
{84C0F098-0883-4B60-88A7-3F1DE62EF226}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {103B4E39-2E6B-4BA0-A51B-F09A25BD55D6}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,84 @@
#include "axistag.h"
AxisTag::AxisTag(QCPAxis* parentAxis) :
QObject(parentAxis),
mAxis(parentAxis)
{
// The dummy tracer serves here as an invisible anchor which always sticks to the right side of
// the axis rect
mDummyTracer = new QCPItemTracer(mAxis->parentPlot());
mDummyTracer->setVisible(false);
mDummyTracer->position->setTypeX(QCPItemPosition::ptAxisRectRatio);
mDummyTracer->position->setTypeY(QCPItemPosition::ptPlotCoords);
mDummyTracer->position->setAxisRect(mAxis->axisRect());
mDummyTracer->position->setAxes(0, mAxis);
mDummyTracer->position->setCoords(1, 0);
// the arrow end (head) is set to move along with the dummy tracer by setting it as its parent
// anchor. Its coordinate system (setCoords) is thus pixels, and this is how the needed horizontal
// offset for the tag of the second y axis is achieved. This horizontal offset gets dynamically
// updated in AxisTag::updatePosition. the arrow "start" is simply set to have the "end" as parent
// anchor. It is given a horizontal offset to the right, which results in a 15 pixel long arrow.
mArrow = new QCPItemLine(mAxis->parentPlot());
mArrow->setLayer("overlay");
mArrow->setClipToAxisRect(false);
mArrow->setHead(QCPLineEnding::esSpikeArrow);
mArrow->end->setParentAnchor(mDummyTracer->position);
mArrow->start->setParentAnchor(mArrow->end);
mArrow->start->setCoords(15, 0);
// The text label is anchored at the arrow start (tail) and has its "position" aligned at the
// left, and vertically centered to the text label box.
mLabel = new QCPItemText(mAxis->parentPlot());
mLabel->setLayer("overlay");
mLabel->setClipToAxisRect(false);
mLabel->setPadding(QMargins(3, 0, 3, 0));
mLabel->setBrush(QBrush(Qt::white));
mLabel->setPen(QPen(Qt::blue));
mLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignVCenter);
mLabel->position->setParentAnchor(mArrow->start);
}
AxisTag::~AxisTag()
{
if (mDummyTracer)
mDummyTracer->parentPlot()->removeItem(mDummyTracer);
if (mArrow)
mArrow->parentPlot()->removeItem(mArrow);
if (mLabel)
mLabel->parentPlot()->removeItem(mLabel);
}
void AxisTag::setPen(const QPen& pen)
{
mArrow->setPen(pen);
mLabel->setPen(pen);
}
void AxisTag::setBrush(const QBrush& brush)
{
mLabel->setBrush(brush);
}
void AxisTag::setText(const QString& text)
{
mLabel->setText(text);
}
void AxisTag::updatePosition(double value)
{
// since both the arrow and the text label are chained to the dummy tracer (via anchor
// parent-child relationships) it is sufficient to update the dummy tracer coordinates. The
// Horizontal coordinate type was set to ptAxisRectRatio so to keep it aligned at the right side
// of the axis rect, it is always kept at 1. The vertical coordinate type was set to
// ptPlotCoordinates of the passed parent axis, so the vertical coordinate is set to the new
// value.
mDummyTracer->position->setCoords(1, value);
// We want the arrow head to be at the same horizontal position as the axis backbone, even if
// the axis has a certain offset from the axis rect border (like the added second y axis). Thus we
// set the horizontal pixel position of the arrow end (head) to the axis offset (the pixel
// distance to the axis rect border). This works because the parent anchor of the arrow end is
// the dummy tracer, which, as described earlier, is tied to the right axis rect border.
mArrow->end->setCoords(mAxis->offset(), 0);
}

View File

@ -0,0 +1,31 @@
#pragma once
#include <QObject>
#include "qcustomplot.h"
class AxisTag : public QObject
{
Q_OBJECT
public:
explicit AxisTag(QCPAxis* parentAxis);
virtual ~AxisTag();
// setters:
void setPen(const QPen& pen);
void setBrush(const QBrush& brush);
void setText(const QString& text);
// getters:
QPen pen() const { return mLabel->pen(); }
QBrush brush() const { return mLabel->brush(); }
QString text() const { return mLabel->text(); }
// other methods:
void updatePosition(double value);
protected:
QCPAxis* mAxis;
QPointer<QCPItemTracer> mDummyTracer;
QPointer<QCPItemLine> mArrow;
QPointer<QCPItemText> mLabel;
};

View File

@ -0,0 +1,10 @@
#include "realTimeDataDisplay.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
realTimeDataDisplay w;
w.show();
return a.exec();
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,137 @@
#include "realTimeDataDisplay.h"
realTimeDataDisplay::realTimeDataDisplay(QWidget* parent)
: QMainWindow(parent)
{
ui.setupUi(this);
mPlot = new QCustomPlot(this);
setCentralWidget(mPlot);
//mPlot->yAxis->setTickLabels(false);
mPlot->axisRect()->axis(QCPAxis::atRight, 0)->setPadding(54);
mGraph1 = mPlot->addGraph(mPlot->xAxis, mPlot->axisRect()->axis(QCPAxis::atRight, 0));
QColor color1(100, 140, 180);
QPen pen;
pen.setStyle(Qt::PenStyle::SolidLine);
pen.setColor(color1);
mGraph1->setPen(pen);
color1.setAlpha(100);
mPlot->graph(0)->setBrush(QBrush(color1));
mPlot->graph(0)->setName("sin(t)+sin(t/0.38)");
mGraph2 = mPlot->addGraph(mPlot->xAxis, mPlot->axisRect()->axis(QCPAxis::atRight, 0));
QColor color2(166, 77, 157);
pen.setStyle(Qt::PenStyle::SolidLine);
pen.setColor(color2);
mGraph2->setPen(pen);
color2.setAlpha(100);
mPlot->graph(1)->setBrush(QBrush(color2));
mPlot->graph(1)->setName("sin(t)");
QSharedPointer<QCPAxisTickerTime> timeTicker(new QCPAxisTickerTime);
timeTicker->setTimeFormat("%h:%m:%s");
mPlot->xAxis->setTicker(timeTicker);
mPlot->xAxis->setRange(0, 16);
mPlot->yAxis->setRange(-2.2, 2.2);
mPlot->xAxis->setLabel("time");
mPlot->yAxis->setLabel("value");
mPlot->plotLayout()->insertRow(0);
QCPTextElement* title = new QCPTextElement(mPlot, "Realtime Data Display");
mPlot->plotLayout()->addElement(0, 0, title);
connect(mPlot, &QCustomPlot::mousePress, this, [=] { xAxisAutoChange = false; });
connect(mPlot, &QCustomPlot::mouseRelease, this, [=] { xAxisAutoChange = true; });
mPlot->setInteractions(QCP::iRangeDrag);
QList<QCPAxis*>list;
list.append(mPlot->xAxis);
mPlot->axisRect()->setRangeDragAxes(list);
mPlot->axisRect()->setupFullAxesBox();
mTimerThread = new QThread(this);
mDataTimer = new QTimer();
connect(mDataTimer, SIGNAL(timeout()), this, SLOT(timerSlot()), Qt::DirectConnection);
connect(mTimerThread, &QThread::finished, mDataTimer, &QObject::deleteLater);
connect(mTimerThread, &QThread::finished, mTimerThread, &QObject::deleteLater);
connect(this, &realTimeDataDisplay::updateUICustomPlot, this, &realTimeDataDisplay::onUpdateUICustomPlot);
mTimerThread->start();
mDataTimer->start(16);
mDataTimer->moveToThread(mTimerThread);
qDebug() << "this Thread:" << QThread::currentThreadId() << QThread::currentThread();
mTag1 = new AxisTag(mGraph1->valueAxis());
mTag1->setPen(mGraph1->pen());
mTag2 = new AxisTag(mGraph2->valueAxis());
mTag2->setPen(mGraph2->pen());
mPlot->legend->setVisible(true);
mPlot->legend->setBrush(QColor(255, 255, 255, 150));
}
realTimeDataDisplay::~realTimeDataDisplay()
{
if (mDataTimer)
{
mTimerThread->quit();
mTimerThread->wait();
//connect: &QObject::deleteLater不需要delete
mTimerThread = nullptr;
mDataTimer = nullptr;
}
}
void realTimeDataDisplay::onUpdateUICustomPlot(double key, double v1, double v2)
{
if (xAxisAutoChange)
mPlot->xAxis->setRange(key, 16, Qt::AlignRight);
mTag1->updatePosition(v1);
mTag2->updatePosition(v2);
if (v1 > 0)
mTag1->setText("+" + QString::number(v1, 'f', 2));
else
mTag1->setText(QString::number(v1, 'f', 2));
if (v2 > 0)
mTag2->setText("+" + QString::number(v2, 'f', 2));
else
mTag2->setText(QString::number(v2, 'f', 2));
mPlot->replot();
}
void realTimeDataDisplay::timerSlot()
{
//qDebug() << "timerSlot Thread:" << QThread::currentThreadId() << QThread::currentThread();
static QTime timeStart = QTime::currentTime();
double key = timeStart.msecsTo(QTime::currentTime()) / 1000.0;
static double lastFpsKey;
static int frameCount;
++frameCount;
if (key - lastFpsKey > 2) // average fps over 2 seconds
{
ui.statusBar->showMessage(QString("%1 FPS").arg(frameCount / (key - lastFpsKey), 0, 'f', 0), 0);
lastFpsKey = key;
frameCount = 0;
}
mPlot->graph(0)->addData(key, qSin(key) + qSin(key / 0.3843));
mPlot->graph(1)->addData(key, qSin(key));
double graph1Value = mGraph1->dataMainValue(mGraph1->dataCount() - 1);
double graph2Value = mGraph2->dataMainValue(mGraph2->dataCount() - 1);
emit updateUICustomPlot(key, graph1Value, graph2Value);
//mTag1->updatePosition(graph1Value);
//mTag2->updatePosition(graph2Value);
//if (graph1Value > 0)
// mTag1->setText("+" + QString::number(graph1Value, 'f', 2));
//else
// mTag1->setText(QString::number(graph1Value, 'f', 2));
//if (graph2Value > 0)
// mTag2->setText("+" + QString::number(graph2Value, 'f', 2));
//else
// mTag2->setText(QString::number(graph2Value, 'f', 2));
//mPlot->replot();
}

View File

@ -0,0 +1,39 @@
#pragma once
#include <QtWidgets/QMainWindow>
#include <QTimer>
#include <QThread>
#include "ui_realTimeDataDisplay.h"
#include "qcustomplot.h"
#include "AxisTag.h"
class realTimeDataDisplay : public QMainWindow
{
Q_OBJECT
public:
realTimeDataDisplay(QWidget* parent = nullptr);
~realTimeDataDisplay();
signals:
void updateUICustomPlot(double key, double v1, double v2);
private slots:
void timerSlot();
void onUpdateUICustomPlot(double key, double v1, double v2);
private:
Ui::realTimeDataDisplayClass ui;
QCustomPlot* mPlot = nullptr;
QTimer* mDataTimer = nullptr;
QThread* mTimerThread = nullptr;
QPointer<QCPGraph> mGraph1;
QPointer<QCPGraph> mGraph2;
QSharedPointer<QCPAxisTickerText> textTicker;
AxisTag* mTag1;
AxisTag* mTag2;
bool xAxisAutoChange = true;
};

View File

@ -0,0 +1,4 @@
<RCC>
<qresource prefix="realTimeDataDisplay">
</qresource>
</RCC>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>realTimeDataDisplayClass</class>
<widget class="QMainWindow" name="realTimeDataDisplayClass">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>840</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle">
<string>realTimeDataDisplay</string>
</property>
<widget class="QWidget" name="centralWidget"/>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="realTimeDataDisplay.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{84C0F098-0883-4B60-88A7-3F1DE62EF226}</ProjectGuid>
<Keyword>QtVS_v304</Keyword>
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">10.0.22000.0</WindowsTargetPlatformVersion>
<QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
<Import Project="$(QtMsBuild)\qt_defaults.props" />
</ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
<QtInstall>Qt5.11.2</QtInstall>
<QtModules>core;gui;widgets;printsupport</QtModules>
<QtBuildConfig>release</QtBuildConfig>
</PropertyGroup>
<Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
<Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
</Target>
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="Shared" />
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(QtMsBuild)\Qt.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
<ClCompile>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<QtRcc Include="realTimeDataDisplay.qrc" />
<QtUic Include="realTimeDataDisplay.ui" />
<QtMoc Include="realTimeDataDisplay.h" />
<ClCompile Include="AxisTag.cpp" />
<ClCompile Include="qcustomplot.cpp" />
<ClCompile Include="realTimeDataDisplay.cpp" />
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<QtMoc Include="qcustomplot.h" />
</ItemGroup>
<ItemGroup>
<QtMoc Include="AxisTag.h" />
<ClInclude Include="x64\Release\uic\ui_realTimeDataDisplay.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
<Import Project="$(QtMsBuild)\qt.targets" />
</ImportGroup>
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Form Files">
<UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
<Extensions>ui</Extensions>
</Filter>
<Filter Include="Translation Files">
<UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
<Extensions>ts</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<QtRcc Include="realTimeDataDisplay.qrc">
<Filter>Resource Files</Filter>
</QtRcc>
<QtUic Include="realTimeDataDisplay.ui">
<Filter>Form Files</Filter>
</QtUic>
<QtMoc Include="realTimeDataDisplay.h">
<Filter>Header Files</Filter>
</QtMoc>
<ClCompile Include="realTimeDataDisplay.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="qcustomplot.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="AxisTag.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<QtMoc Include="qcustomplot.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="AxisTag.h">
<Filter>Header Files</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<ClInclude Include="x64\Release\uic\ui_realTimeDataDisplay.h">
<Filter>Form Files</Filter>
</ClInclude>
</ItemGroup>
</Project>