如何在Qt中绘制和编辑折线图

时间:2012-09-01 11:18:22

标签: c++ qt graph qwt linegraph

我需要在Qt中绘制图表。用户shold具有创建和删除顶点(点)和边(线)的能力。用户也可以用鼠标移动顶点。

Qwt可以帮助我,还是应该使用别的东西(比如用QWidget + QPainter画我自己)

P.S。可能存在未连接的顶点。

3 个答案:

答案 0 :(得分:4)

我找到了Qt示例 - Eastic Nodes。经过一番努力后,我做了我想要的东西 更新:Here是我的代码,如果有人有兴趣。

答案 1 :(得分:1)

使用QGLWidget结合QStack来保存顶点,实体类型及其信息(Color,LineWidth)。

你重载QGLWidgets虚函数initializeGL,resizeGL和paintGL

以下是一个例子:

#ifndef DDEVICE_H
#define DDEVICE_H

#include <QtOpenGL/QGLWidget>
#include "Renderer.h"

class dDevice : public QGLWidget
{
    Q_OBJECT
public:
    explicit dDevice(QWidget *parent = 0);
protected:
    void initializeGL(){            Renderer::Engine()->init();     }
    void resizeGL(int w, int h){    Renderer::Engine()->resize(w,h);}
    void paintGL(){                 Renderer::Engine()->draw();     }
};

#endif // DDEVICE_H

和渲染器单身。

#ifndef RENDERER_H
#define RENDERER_H
#include <QtOpenGL/QtOpenGL>
#include "Types.h"

class Renderer : public EStack
{
    int width,height,aspect_ratio;
public:
    static Renderer* Engine();
    bool init();
    bool resize(int W,int H);
    bool draw();
private:
    Renderer():EStack(){ }
    static Renderer* m_pInstance;
};

#endif // RENDERER_H

EStack是实体堆栈,包含线条,贝塞尔曲线,圆弧,圆盘,圆和折线的QStacks。哪个是包含顶点,颜色,线宽结构的实体结构。

使用四个控制点绘制Bezier曲线,并且#defined REGEN量常量通常高于36。在Renderer :: draw中添加它。 reziseGL也调用了paintGL。

                Entities::Bezier temp = bcurves().at(i);
                glLineWidth(temp.LW.value); // change LWidth

                glColor3f( temp.CL.R, temp.CL.G, temp.CL.B );
                double A[] = { temp.cPoints.points[0].X , temp.cPoints.points[0].Y };
                double B[] = { temp.cPoints.points[1].X , temp.cPoints.points[1].Y };
                double C[] = { temp.cPoints.points[2].X , temp.cPoints.points[2].Y };
                double D[] = { temp.cPoints.points[3].X , temp.cPoints.points[3].Y };
                glBegin(GL_LINE_STRIP);
                double a = 1.0;
                for(int ii=0;ii<=WW_BEZIER_ACCURACY;ii++){
                    double b = 1.0-a;
                    double X = A[0]*a*a*a + B[0]*3*a*a*b + C[0]*3*a*b*b + D[0]*b*b*b;
                    double Y = A[1]*a*a*a + B[1]*3*a*a*b + C[1]*3*a*b*b + D[1]*b*b*b;
                    glVertex2d(X,Y);
                    a = a - 1.0/WW_BEZIER_ACCURACY;
                }
                glEnd();

或使用其实体结构的简单线条。

            Entities::Line temp = lines().at(i);

            glLineWidth(temp.LW.value); // change LWidth
            glBegin(GL_LINE_STRIP);
            glColor3f(temp.CL.R,temp.CL.G,temp.CL.B);

            glVertex2d(temp.A.X,temp.A.Y);
            glVertex2d(temp.B.X,temp.B.Y);
            glEnd();
            glLineWidth(WW_DEFAULT_LWIDTH); // reset LWidth

这也绘制了一条线条。

glBegin(GL_LINE_STRIP);
glVertex2d(0,0);
glVertex2d(.5,.5);
glEnd();

答案 2 :(得分:1)

Qwt可以用来做到这一点。看一下Qwt包的examples目录中的event_filter示例。该示例不允许添加和删除顶点,但添加它不应该太难。

我会推荐Qwt,因为它提供了许多您需要的基本绘图功能,并且非常易于扩展,因此您可以轻松添加新功能。