C++ 如何为QLineSeries/QXYSeries设置自定义点标签格式?
上下文:我尝试在C++ 如何为QLineSeries/QXYSeries设置自定义点标签格式?,c++,qt,qtcharts,C++,Qt,Qtcharts,上下文:我尝试在QChart上绘制QLineSeries,以打印值随时间的变化。 因此,X轴(横坐标)是QDateTimeAxis,Y轴(纵坐标)是QValueAxis 问题:我想显示点标签。但是我找不到如何设置datetime所需的格式。 默认情况下,标签只能绘制点的整数值,这是我想要的坐标值。 但对于横坐标(datetime)值,它打印自上一个历元(1970-01-01T00:00:00.000)以来经过的毫秒数。 我想更改日期时间的格式以匹配“hh:mm:ss”(这是我用来在QDateTi
QChart
上绘制QLineSeries
,以打印值随时间的变化。因此,X轴(横坐标)是
QDateTimeAxis
,Y轴(纵坐标)是QValueAxis
问题:我想显示点标签。但是我找不到如何设置datetime所需的格式。默认情况下,标签只能绘制点的整数值,这是我想要的坐标值。
但对于横坐标(datetime)值,它打印自上一个历元(1970-01-01T00:00:00.000)以来经过的毫秒数。
我想更改日期时间的格式以匹配“hh:mm:ss”(这是我用来在
QDateTimeAxis
上显示刻度的格式)
我知道存在允许指定格式的,但它只接受@xPoint
和@yPoint
格式标记(如文档中所示)
- 您可以在此处找到该问题的图片:
QDateTimeAxis
的格式,但不能在点标签上设置
生成此输出的代码示例基于提供的示例。我只是添加了更多的点,并取消了行//ls->setpointlabelvisible(true)的注释代码>
问题:是否有一种方法可以使用自定义格式打印@xPoint
标签(理想情况下匹配QDateTime::toString(“hh:mm:ss”)
)?如果是,如何操作?不支持。您可以为所谓的QXYDatetimeSeries
派生一个新类,它遵循通过查看代码实现的相同操作。您可能还希望更改QXYSeriesPrivate::drawSeriesPointLabels
源代码以支持您的行为。不要忘记将您的更改推送到QtGit存储库,以便其他人也可以使用它 如Soheim所述,QtCharts提供的点标签格式对此太有限
如果你不想让QtCharts内部的东西弄脏你的手,你可以用另一种方法来解决你的问题:自己画文本标签
从QGraphicsObject
派生自定义图形项:
class PointLabelsItem : public QGraphicsObject
{
Q_OBJECT
public:
PointLabelsItem(QtCharts::QChart *parent = nullptr);
virtual QRectF boundingRect() const;
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);
public slots:
void setRect(const QRectF &area);
void setAxis(const QAbstractAxis *axis, Qt::Alignment alignment);
// setter for either source Q*Series or points / point labels
protected:
QRectF area;
// const axes*
// const series* or points/labels
};
在实施过程中:
PointLabelsItem::PointLabelsItem(QtCharts::QChart *parent)
: QGraphicsObject(parent)
{
setZValue(10); // put above series
connect(parent, &QtCharts::QChart::plotAreaChanged,
this, &PointLabelsItem::setRect);
}
QRectF PointLabelsItem::boundingRect() const
{
return area;
}
void PointLabelsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
// translate between data coordinates and scene coordinates
// by making use of `area` and the axes' ranges, OR via
// qobject_cast<QtCharts::QChart>(parent())->mapToPosition()
// then draw custom point label texts at the corresp. positions
}
void PointLabelsItem::setRect(const QRectF &newArea)
{
area = newArea;
update();
}
void setAxis(const QAbstractAxis *axis, Qt::Alignment alignment)
{
disconnect(/* old axis member variable */);
// set corresp. axis member variable here
connect(axis, &QtCharts::QValueAxis::rangeChanged, this, [this] { update(); });
}
那是裸露的骨头
您还可以决定将QGRaphicsTextItem
设置为pointlabelitem
的子项(即,将此
设置为其父项的成员)。通过这种方式,您可以启用用户与标签的交互。谢谢您的回答,我已经想到了这一点。但如果可能的话,我想避免。所以答案是否定的。我不会修改源代码,因为它应该是可移植的,并且可以在其他平台上工作(这显然不会有我的修改,除非Qt接受最终的pull请求)。我将只绘制@yPoint
s。当我有时间时,我会重新定义我自己的series类。如果我理解得当,我的想法是在QChart
中绘制另一个QGraphicsObject
,它将独立绘制标签。听起来是个不错的解决办法。我猜RangeSelectItem
(对于setRect()
实现中的作用域)是指PointLabelItem
。很抱歉,这是一个复制粘贴错误。我为这个例子修改了更具体的类。
auto pointLabels = new PointLabelsItem(chart);
// set axes, series