6

I am writing an application in C++ with QT where you have n points and compute the convex hull of this. However, once this is computed I have no idea how to plot the points and draw the border of the hull. Making menu buttons and such is simple enough, but I'm not sure I know the tools to do this.

How do you do this?

  • Possible duplicate of: Making plot in Qt (http://stackoverflow.com/questions/1491362/making-plot-in-qt) – yasouser Oct 18 '11 at 03:25

4 Answers4

12

Graphics View, addEllipse

QGraphicsView does 2D plotting very well and gives you many options for how to display it. It isn't as tailored for plotting scientific data as much as qwt, but just for showing a bunch of points, or geometry or animations and lots of other things it works very well. See Qt's Graphics View Framework documentation and examples.

Here is how you plot a bunch of points in a QGraphicsScene and show it in a QGraphicsView.

#include <QtGui/QApplication>

#include <QGraphicsView>
#include <QGraphicsScene>
#include <QPointF>
#include <QVector>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QVector <QPointF> points;

    // Fill in points with n number of points
    for(int i = 0; i< 100; i++)
       points.append(QPointF(i*5, i*5));

    // Create a view, put a scene in it and add tiny circles
    // in the scene
    QGraphicsView * view = new QGraphicsView();
    QGraphicsScene * scene = new QGraphicsScene();
    view->setScene(scene);

    for(int i = 0; i< points.size(); i++)
        scene->addEllipse(points[i].x(), points[i].y(), 1, 1);

    // Show the view
    view->show();

    // or add the view to the layout inside another widget

    return a.exec();
}

Note: You will probably want to call setSceneRect on your view, otherwise the scene will just auto-center it. Read the descriptions for QGraphicsScene and QGraphicsView in the Qt Documentation. You can scale the view to show more or less of the scene and it can put scroll bars in. I answered a related question where I show more about what you can do with a QGraphicsView that you may want to look at also.

phyatt
  • 18,472
  • 5
  • 61
  • 80
6

You can just create a custom class deriving from QWidget where you override the void paintEvent(QPaintEvent* event) method. In that you put the points into some sort of point list, either std::vector<QPoint> or QList<QPoint> and then paint it with a Polyline method. For instance:

void Foo::paintEvent(QPaintEvent* event)
{
  QPainter painter(this);
  std::vector<QPoint> points;
  // Fill points with the points
  painter.drawPolyLine(points.data(), static_cast<int>(points.size()));
}
Dominik Grabiec
  • 10,315
  • 5
  • 39
  • 45
  • i tried this, but got compilation error: 'QPainter painter' has initializer but incomplete type' – Ohad Cohen Mar 10 '15 at 18:20
  • Well, the @Ohad may be long gone but for other passers by the "incomplete type" error generally indicates that you are using a Qt object for which you have not included the appropriate header (i.e. add `#include ` to the top of the file). As an aside it would appear that there is a header somewhere that provides forward declarations of all the Qt classes (i.e. `class QPainter;` and the like) making the compiler recognize that there exists such a class, but not know anything more about it and resulting in the unfamiliar error message. – dmckee --- ex-moderator kitten Jan 10 '19 at 23:52
3

There is a charting library, qwt, that provides Qt widgets for - erm - charting purposes.

Clare Macrae
  • 3,670
  • 2
  • 31
  • 45
  • Indeed, I noticed this, but I'm hoping to do it with only QT, for compatibility purposes with some peers. –  Oct 17 '11 at 23:13
  • 2
    You can compile qwt right into your project, and it's Qt based. I don't see how this would affect compatibility. – Chris Oct 17 '11 at 23:55
1

Qt Charts, QML or GraphicsView

This was going to be an update to my QGraphics View example, but it got kind of long, and it really is a completely different method to answer the question.

Qt Charts (LGPL available since 2016) is a great way to do this without needing a third party library.

https://doc.qt.io/qt-5/qlineseries.html#QLineSeries

QLineSeries* series = new QLineSeries();
series->append(0, 6);
series->append(2, 4);
...
chart->addSeries(series);

For the convex hull example specifically, you probably want the QAreaSeries chart.

https://doc.qt.io/qt-5/qtcharts-areachart-example.html
https://doc.qt.io/qt-5/qareaseries.html

QLineSeries *series0 = new QLineSeries();
QLineSeries *series1 = new QLineSeries();
*series0 << QPointF(1, 5) << QPointF(3, 7) << QPointF(7, 6) << QPointF(9, 7) << QPointF(12, 6)
         << QPointF(16, 7) << QPointF(18, 5);
*series1 << QPointF(1, 3) << QPointF(3, 4) << QPointF(7, 3) << QPointF(8, 2) << QPointF(12, 3)
         << QPointF(16, 4) << QPointF(18, 3);
QAreaSeries *series = new QAreaSeries(series0, series1);

Hope that helps.

phyatt
  • 18,472
  • 5
  • 61
  • 80