此示例演示了QCustomPlot 标签的更高级用法。创建一个新的小型类
AxisTag
,该类管理一组条目,这些条目一起形成指向轴并突出显示特定坐标的标签。
为了在主应用程序中展示它,在rect的右侧创建了两个轴,并制作了两个相应的标签来指示两个图形的最右边的数据点值,这些值不断更新。
本教程随附的示例项目称为
axis-tags-example
,是完整软件包下载的一部分
一个新类来处理所涉及的项目
您在上面的屏幕快照中看到的标签包含两个可见的条目:一个
QCPItemText
,它为我们提供当前坐标(由矩形边框包围的文本),以及一个
QCPItemLine
,其头部的线尾设置为箭头形状,从而提供了箭头指向靠左。
但是,还有另一个不可见的条目可以帮助您定位标签。甲
QCPItemTracer
在各坐标值的高度坐在右轴矩形边界(内轴的水平位置)。它提供了其他条目的主要父锚,因此上下移动该跟踪器将上下移动整个标签。
在
MainWindow
代码中单独管理所有三个条目将容易出错,并且样式不好。因此
AxisTag
,将创建一个新类,该类负责设置和处理这三个条目。这是
AxisTag
该类的标题代码:
#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;
为了使本示例清楚起见,将接口最小化。在实际情况下,可能需要此类的更多自定义功能和额外功能,例如,一种泛化功能还可以支持其他轴方向。
下一个代码段是AxisTag
该类的实现 。在其构造函数中,三个条目之间建立了以下锚定父子关系。青色的蓝色圆圈表示QCPItemTracer位置,QCPItemLine结束/起始位置和QCPItemText位置。
有关代码段的说明
#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);
现在,主应用程序利用了这个新AxisTag
类,从而避免了直接进行项目操作而弄脏手的情况–所有这些操作都在AxisTag
实例内部进行处理。
这是MainWindow
该类的标题。和以前一样,可以在嵌入式注释中找到解释
#include <QMainWindow>
#include "qcustomplot.h"
#include "axistag.h"
namespace Ui {
class MainWindow;
class MainWindow : public QMainWindow
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void timerSlot();
private:
Ui::MainWindow *ui;
QCustomPlot *mPlot;
QPointer<QCPGraph> mGraph1;
QPointer<QCPGraph> mGraph2;
AxisTag *mTag1;
AxisTag *mTag2;
QTimer mDataTimer;
最后执行MainWindow
该类。它基本上在右侧设置了两个y轴,两个图形和两个轴标签。在timerSlot()
反复通过一个叫QTimer
。在插槽中,新的数据点被添加到图形中,并且标签通过其方法进行更新。AxisTag::updatePosition
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
mPlot(0),
mTag1(0),
mTag2(0)
ui->setupUi(this);
mPlot = new QCustomPlot(this);
setCentralWidget(mPlot);
// configure plot to have two right axes:
mPlot->yAxis->setTickLabels(false);
connect(mPlot->yAxis2, SIGNAL(rangeChanged(QCPRange)), mPlot->yAxis, SLOT(setRange(QCPRange))); // left axis only mirrors inner right axis
mPlot->yAxis2->setVisible(true);
mPlot->axisRect()->addAxis(QCPAxis::atRight);
mPlot->axisRect()->axis(QCPAxis::atRight, 0)->setPadding(30); // add some padding to have space for tags
mPlot->axisRect()->axis(QCPAxis::atRight, 1)->setPadding(30); // add some padding to have space for tags
// create graphs:
mGraph1 = mPlot->addGraph(mPlot->xAxis, mPlot->axisRect()->axis(QCPAxis::atRight, 0));
mGraph2 = mPlot->addGraph(mPlot->xAxis, mPlot->axisRect()->axis(QCPAxis::atRight, 1));
mGraph1->setPen(QPen(QColor(250, 120, 0)));
mGraph2->setPen(QPen(QColor(0, 180, 60)));
// create tags with newly introduced AxisTag class (see axistag.h/.cpp):
mTag1 = new AxisTag(mGraph1->valueAxis());
mTag1->setPen(mGraph1->pen());
mTag2 = new AxisTag(mGraph2->valueAxis());
mTag2->setPen(mGraph2->pen());
connect(&mDataTimer, SIGNAL(timeout()), this, SLOT(timerSlot()));
mDataTimer.start(40);
MainWindow::~MainWindow()
delete ui;
void MainWindow::timerSlot()
// calculate and add a new data point to each graph:
mGraph1->addData(mGraph1->dataCount(), qSin(mGraph1->dataCount()/50.0)+qSin(mGraph1->dataCount()/50.0/0.3843)*0.25);
mGraph2->addData(mGraph2->dataCount(), qCos(mGraph2->dataCount()/50.0)+qSin(mGraph2->dataCount()/50.0/0.4364)*0.15);
// make key axis range scroll with the data:
mPlot->xAxis->rescale();
mGraph1->rescaleValueAxis(false, true);
mGraph2->rescaleValueAxis(false, true);
mPlot->xAxis->setRange(mPlot->xAxis->range().upper, 100, Qt::AlignRight);
// update the vertical axis tag positions and texts to match the rightmost data point of the graphs:
double graph1Value = mGraph1->dataMainValue(mGraph1->dataCount()-1);
double graph2Value = mGraph2->dataMainValue(mGraph2->dataCount()-1);
mTag1->updatePosition(graph1Value);
mTag2->updatePosition(graph2Value);
mTag1->setText(QString::number(graph1Value, 'f', 2));
mTag2->setText(QString::number(graph2Value, 'f', 2));
mPlot->replot();
此示例演示了QCustomPlot 标签的更高级用法。创建一个新的小型类AxisTag,该类管理一组条目,这些条目一起形成指向轴并突出显示特定坐标的标签。为了在主应用程序中展示它,在rect的右侧创建了两个轴,并制作了两个相应的标签来指示两个图形的最右边的数据点值,这些值不断更新。本教程随附的示例项目称为axis-tags-example,是完整软件包下载的一部分一个新类来处理所涉及的项目您在上面的屏幕快照中看到的标签包含两个可见的条目:一个QCPItemText,它为我们提供当前坐..
添加标题,初始化:
ui.customPlot->plotLayout()->insertRow(0);
m_title = new QCPTextElement(ui.customPlot, "初始");
ui.customPlot->plotLayout()->addElement(0, 0, m_title);
在需要更改标题的地方直接使用QCPTextElement类的setText设置新的标题,然后
http://www.qcustomplot.com/
当您熟悉使用QCustomPlot进行数据可视化的基础知识并且希望了解有关特定功能或更多高级概念的更多信息时,本文档对于作为参考特别有用。请参阅类概述,以获得解释QCustomPlot库最重要的类之间的关系的图。
绘图表是在QCusto.
在 QCustomPlot 中,可以通过以下步骤实现自定义 X 轴字符串标签:
1. 首先,创建一个 QCPAxisTickerText 对象,该对象可以用于自定义 X 轴标签。
```cpp
QSharedPointer<QCPAxisTickerText> textTicker(new QCPAxisTickerText);
2. 然后,通过 addTicks() 函数向 QCustomPlot 中添加自定义的标签。addTicks() 函数需要一个 QVector<QCPAxisTickerText::TickData> 类型的参数,该参数包含每个标签的位置和文本。
```cpp
QVector<QCPAxisTickerText::TickData> ticks;
ticks << QCPAxisTickerText::TickData(1, "Label 1");
ticks << QCPAxisTickerText::TickData(2, "Label 2");
// ...
textTicker->addTicks(ticks);
3. 最后,将自定义的 QCPAxisTickerText 对象设置为 X 轴的 ticker。
```cpp
customPlot->xAxis->setTicker(textTicker);
完整的代码如下所示:
```cpp
// 创建自定义的 QCPAxisTickerText 对象
QSharedPointer<QCPAxisTickerText> textTicker(new QCPAxisTickerText);
// 添加自定义的标签
QVector<QCPAxisTickerText::TickData> ticks;
ticks << QCPAxisTickerText::TickData(1, "Label 1");
ticks << QCPAxisTickerText::TickData(2, "Label 2");
// ...
textTicker->addTicks(ticks);
// 将自定义的 QCPAxisTickerText 对象设置为 X 轴的 ticker
customPlot->xAxis->setTicker(textTicker);
注意,如果 X 轴的范围是连续的数值而不是离散的标签,那么可以使用 QCPAxisTicker 或 QCPAxisTickerFixed 类来自定义 X 轴的刻度。
CSDN-Ada助手:
lib60870-IEC 60870-5-101 / 104 C源代码库用户指南-版本2.3.0 -第四部分
helloworld′:
lib60870-IEC 60870-5-101 / 104 C源代码库用户指南-版本2.3.0--第一部分
pppuddin:
20. QCustomPlot QCPGraph类参考
不正经的kimol君:
qModbus开源QT的modbus测试程序
AlanBruce: