weixin_41822728 2024-04-22 10:58 采纳率: 0%
浏览 29
已结题

qt 散点图自定义图形

用qt绘制散点图时 图例和绘制图形不相同 表格中绘制图形根据数据有多种形状 qt只能改变单个图例形状
无法实现自定义图形

img

  • 写回答

22条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-04-22 10:58
    关注
    获得0.45元问题酬金

    引自免费微信小程序:皆我百晓生

    在Qt中创建自定义形状的散点图可能需要一些额外的工作,因为Qt默认的QGraphicsScene和QGraphicsView不支持直接为每个数据点设置不同的图形。不过,可以通过自定义QGraphicsItem类来实现这个功能。下面是一个详细的步骤指南以及示例代码。

    首先,你需要创建一个继承自QGraphicsItem的类,例如MyCustomPlotPoint,并重写其boundingRect、paint和shape方法。

    1. 创建MyCustomPlotPoint.h文件:
    #ifndef MYCUSTOMPLOTPoint_H
    #define MYCUSTOMPLOTPoint_H
    
    #include <QObject>
    #include <QPainterPath>
    #include <QGraphicsItem>
    
    class MyCustomPlotPoint : public QGraphicsItem
    {
    public:
        explicit MyCustomPlotPoint(const QPointF &pos, QObject *parent = nullptr);
        ~MyCustomPlotPoint();
    
        QRectF boundingRect() const override;
        void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
        QPainterPath shape() const override;
    
    private:
        QPointF m_position;
    };
    
    #endif // MYCUSTOMPLOTPoint_H
    
    1. 创建MyCustomPlotPoint.cpp文件:
    #include "MyCustomPlotPoint.h"
    
    #include <QPen>
    #include <QBrush>
    
    MyCustomPlotPoint::MyCustomPlotPoint(const QPointF &pos, QObject *parent)
        : QGraphicsItem(parent), m_position(pos)
    {}
    
    MyCustomPlotPoint::~MyCustomPlotPoint()
    {}
    
    QRectF MyCustomPlotPoint::boundingRect() const
    {
        return QRectF(m_position.x() - 5, m_position.y() - 5, 10, 10); // 可以调整大小
    }
    
    void MyCustomPlotPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
        painter->setPen(Qt::black);
        painter->setBrush(Qt::red);
    
        switch (static_cast<int>(dataShape())) { // 在实际应用中,这里的数据形状可以根据你的需求进行替换
            case 1: // Circle
                painter->drawEllipse(m_position.x(), m_position.y(), 5, 5);
                break;
            case 2: // Square
                painter->drawRect(m_position.x(), m_position.y(), 10, 10);
                break;
            case 3: // Triangle
                QPainterPath path;
                path.moveTo(m_position.x() + 5, m_position.y());
                path.lineTo(m_position.x(), m_position.y() + 5);
                path.lineTo(m_position.x() - 5, m_position.y());
                path.closeSubpath();
                painter->drawPath(path);
                break;
            default:
                break;
        }
    }
    
    QPainterPath MyCustomPlotPoint::shape() const
    {
        QPainterPath path;
        path.addRect(boundingRect()); // 用于碰撞检测
        return path;
    }
    
    1. 然后,在主窗口或相关类中添加绘图逻辑:
    // 假设你已经有了一个包含数据的容器,比如std::vector<QPointF> dataPoints,其中包含了坐标和对应的数据形状
    for (const auto &point : dataPoints) {
        MyCustomPlotPoint *customPoint = new MyCustomPlotPoint(point, scene);
        customPoint->setDataShape(someDataShapeFunction(point)); // 这里根据你的需求获取对应的数据形状
        scene->addItem(customPoint);
    }
    

    在这个例子中,我们为每个数据点创建了一个MyCustomPlotPoint对象,并设置了不同的形状。你可以根据数据点的具体信息(例如频率)来决定它们应该显示为什么样的形状。然后将这些自定义点添加到QGraphicsScene中。

    注意,这只是一个基础的实现,如果你需要更复杂的图例功能,你可能需要创建一个单独的图例视图,并且手动同步它与图表中的标记。对于这个问题,你可能需要使用QGraphicsProxyWidget来嵌入一个简单的QLabel,然后通过事件监听器来更新图例中的图形。

    关于图例的自定义,由于Qt本身并不支持完全自定义图例,所以你可能需要自己创建一个QGraphicsLinearLayout或其他布局管理器,放置QLabels或自定义的小部件来表示不同形状的点。当用户点击图例时,可以触发一个事件处理函数,用来切换图表中所有点的形状。

    这是一个复杂的问题,涉及到多个部分的定制,但以上代码提供了一个基本的起点。你可以在此基础上扩展,满足你的具体需求。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 4月30日
  • 创建了问题 4月22日