I need to draw a graph in Qt. User shold have an ability to create and delete vertices(dots) and edges(lines). Also user could move vertices with a mouse.

Can Qwt help me with that or should i use something else (for example draw it my self with QWidget + QPainter)

P.S. There could be vertices that are not connected.

有帮助吗?

解决方案

I found Qt example - Eastic Nodes. And after some work with it i made what i wanted.
Update: Here is my code if anyone is interested.

其他提示

Using QGLWidget combined with a QStack to hold the vertices, the entity types and their information (Color, LineWidth).

You overload QGLWidgets virtual functions initializeGL , resizeGL and paintGL

Here's an example:

#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

And the Renderer singleton.

#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 is the Entities stack, a class containing QStacks of lines, bezier curves, arcs, disks, circles and polylines. Which are entity structs containing vertex,color,linewidth structs.

Drawing a Bezier curve with four control points and a #defined REGEN amount constant usually above 36 . Add this in Renderer::draw. reziseGL calls paintGL too.

                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();

Or a simple line strip using its entity struct.

            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

This also draws a line strip.

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

Qwt can be used to do this. Take a look at the event_filter example in the examples directory of the Qwt package. That example does not allow adding and deleting of vertices, but it should not be too hard to add it.

I would reccomend Qwt since it provides a lot of the base plotting functionality that you need and is very extensible so you can add new functionality easily.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top