在 QtCharts 上显示文本

问题描述 投票:0回答:3

我正在使用 QtCharts 类来制作折线图。我希望能够在图表本身上添加注释/文本。我该怎么做? 我找到了一个与我想要的类似的示例“https://doc.qt.io/qt-5/qtcharts-callout-example.html”有更简单的方法吗?

c++ qt user-interface qtwidgets
3个回答
1
投票

这是我的版本。可能有错误

textitem.h

#pragma once

#include <QtCharts/QChartGlobal>
#include <QtWidgets/QGraphicsItem>

QT_CHARTS_BEGIN_NAMESPACE
class QChart;
class QAbstractSeries;
QT_CHARTS_END_NAMESPACE

QT_CHARTS_USE_NAMESPACE


class TextItem : public QGraphicsItem {
public:
    TextItem(QString text, QPoint pos, QChart *chart, QAbstractSeries *series);
    QRectF boundingRect() const override;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;

    void setText(const QString &text);
    void setAnchor(QPointF point);
private:
    QChart *_chart;
    QAbstractSeries *_series;
    QString _text;
    QRectF _textRect;
    QPointF _anchor;
};

文本项.cpp

#include "textitem.h"
#include <QtCharts/QChart>
#include <QPainter>
#include <QRect>

TextItem::TextItem(QString text, QPoint pos, QChart *chart, QAbstractSeries *series)
    : QGraphicsItem(chart), _chart(chart), _series(series), _anchor(pos) {
    setText(text);
}

QRectF TextItem::boundingRect() const {
    QPointF anchor = mapFromParent(_chart->mapToPosition(_anchor, _series));
    QRectF rect;
    rect.setLeft(qMin(_textRect.left(), anchor.x()));
    rect.setRight(qMax(_textRect.right(), anchor.x()));
    rect.setTop(qMin(_textRect.top(), anchor.y()));
    rect.setBottom(qMax(_textRect.bottom(), anchor.y()));
    return rect;
}

void TextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
    Q_UNUSED(option)
    Q_UNUSED(widget)
    QPointF anchor = mapFromParent(_chart->mapToPosition(_anchor, _series));
    painter->drawText(anchor, _text);
}

void TextItem::setText(const QString &text) {
  _text = text;
  QFontMetrics metrics((QFont()));
  _textRect = metrics.boundingRect(QRect(0, 0, 150, 150),
                                   Qt::AlignLeft, _text);
  _textRect.translate(5, 5);
  prepareGeometryChange();
}

void TextItem::setAnchor(QPointF point) { _anchor = point; }

0
投票

我知道这是一个迟到的回复,与你不再相关,尽管它可能对其他人来说:

据我所知,他们已经使用了一种非常简单的方法来做到这一点。 在他们的示例中,他们使用 QGraphicsTextItem 在图表中的特定位置添加文本。

假设您有一个系列,并且想要向该系列中图表中可见的每个点添加文本。 这是一个 (python PySide6) 示例,说明如何执行此操作(您可以在 C++ 中以相同的方式执行此操作):

chart = QChart()  # some chart
series = QScatterSeries()  # some series which has been added to the chart

# create text items and add to chart
my_text_items = []
for i in range(series.count()):
    text_item = QGraphicsTextItem("point with idx: {}".format(i), parent=chart)
    my_text_items.append(text_item)


# define function to set/update the position of the text items (has to be called during resize)
def update_position_of_text_items(text_items, series):
    for i, text_item in enumerate(text_items):
        # get point at index i
        point = series.at(i)

        # map its position of the series to the position in the chart
        position_in_chart = series.chart().mapToPosition(point, series)

        # set the position of the text item at index i accordingly
        text_item.setPos(position_in_chart)


update_position_of_text_items(my_text_items, series)

调整小部件大小时,请务必调用

update_position_of_text_items(..)


0
投票

这是使用

QGraphicsTextItem
的解决方案:

MyTextItem.h

#pragma once

#include <QtCharts/QChartGlobal>
#include <QtWidgets/QGraphicsTextItem>

class MyTextItem : public QGraphicsTextItem {
  Q_OBJECT
 public:
  MyTextItem(QString text, QPoint pos, QChart *chart, QAbstractSeries *series);
  void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;

 private:
  QChart *_chart;
  QAbstractSeries *_series;
  QPointF _pos;
};

MyTextItem.cpp

#include "qtext_item.h"

#include <QPainter>
#include <QRect>
#include <QtCharts/QChart>

MyTextItem::MyTextItem(QString text, QPoint pos, QChart *chart, QAbstractSeries *series)
    : QGraphicsTextItem(text, chart), _chart(chart), _series(series), _pos(pos) {
  _chart->scene()->addItem(this);
}

void MyTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
  QPointF anchor = _chart->mapToScene(_chart->mapToPosition(_pos, _series));
  setPos(anchor);
  QGraphicsTextItem::paint(painter, option, widget);
}

但是,我不推荐此解决方案,因为重新绘制比 @kto-to 提出的解决方案慢(滞后)

© www.soinside.com 2019 - 2024. All rights reserved.