Qt GUIで折れ線を描く:QPainter::drawPolyline()の使い方とサンプルコード


QPainter::drawPolyline()は、Qt GUIライブラリで提供される関数の一つであり、複数の点を繋いで折れ線を描くために使用されます。これは、線画や図形の描画など、様々なグラフィック表現において重要な役割を果たします。

構文

void QPainter::drawPolyline(const QPointArray &pointArray, bool closed = false);

引数

  • closed: 折れ線を閉じ、最後の点と最初の点を繋ぐかどうかを指定する。trueの場合、閉じ、falseの場合は開いた折れ線を描画します。
  • pointArray: 描画する点の配列

詳細

QPainter::drawPolyline()は、引数として渡された点の配列を基に、折れ線を描画します。各点は、QPoint構造体によって表現されます。折れ線のスタイルは、現在のQPainterの設定によって決定されます。例えば、線の太さや色などは、事前にQPainter::setPen()関数で設定しておくことができます。

QPainter painter(widget);

// 点の配列を作成
QPointArray pointArray;
pointArray.append(QPoint(10, 20));
pointArray.append(QPoint(50, 40));
pointArray.append(QPoint(90, 20));

// 線の太さを設定
painter.setPen(QPen(Qt::red, 2));

// 折れ線を描画
painter.drawPolyline(pointArray, true);

この例では、赤い太さ2のペンで、(10, 20), (50, 40), (90, 20)の点を繋いだ三角形が描画されます。

  • QPainter::drawPolyline()は、様々な形状を描くために応用できます。例えば、曲線を近似するために、多くの点を用いて折れ線を描くことができます。
  • 折れ線を閉じるかどうかは、closed引数で指定できます。閉じた折れ線は、塗りつぶすこともできます。
  • QPainter::drawPolyline()は、複数の点を効率的に描画するのに適しています。多くの点を個別に繋いでいくよりも、処理速度が速くなります。


#include <QApplication>
#include <QWidget>
#include <QPainter>

class MyWidget : public QWidget {
public:
    MyWidget() {
        setWindowTitle("三角形を描く");
        setFixedSize(200, 150);
    }

protected:
    void paintEvent(QPaintEvent *event) override {
        QPainter painter(this);

        // 点の配列を作成
        QPointArray pointArray;
        pointArray.append(QPoint(10, 20));
        pointArray.append(QPoint(50, 80));
        pointArray.append(QPoint(90, 20));

        // 線の太さを設定
        painter.setPen(QPen(Qt::red, 2));

        // 折れ線を描画
        painter.drawPolyline(pointArray, true);
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    MyWidget widget;
    widget.show();
    return app.exec();
}

例2:五角形を描く

#include <QApplication>
#include <QWidget>
#include <QPainter>

class MyWidget : public QWidget {
public:
    MyWidget() {
        setWindowTitle("五角形を描く");
        setFixedSize(250, 200);
    }

protected:
    void paintEvent(QPaintEvent *event) override {
        QPainter painter(this);

        // 点の配列を作成
        QPointArray pointArray;
        pointArray.append(QPoint(50, 30));
        pointArray.append(QPoint(100, 60));
        pointArray.append(QPoint(150, 30));
        pointArray.append(QPoint(130, 100));
        pointArray.append(QPoint(80, 100));

        // 線の太さを設定
        painter.setPen(QPen(Qt::blue, 3));

        // 折れ線を描画
        painter.drawPolyline(pointArray, true);
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    MyWidget widget;
    widget.show();
    return app.exec();
}
#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <math.h>

class MyWidget : public QWidget {
public:
    MyWidget() {
        setWindowTitle("曲線を近似する");
        setFixedSize(300, 200);
    }

protected:
    void paintEvent(QPaintEvent *event) override {
        QPainter painter(this);

        // 点の配列を作成
        QPointArray pointArray;
        for (int i = 0; i <= 100; i++) {
            double x = i * 3;
            double y = 50 + 20 * sin(2 * M_PI * x / 100);
            pointArray.append(QPoint(x, y));
        }

        // 線の太さを設定
        painter.setPen(QPen(Qt::green, 1));

        // 折れ線を描画
        painter.drawPolyline(pointArray, false);
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    MyWidget widget;
    widget.show();
    return app.exec();
}


代替候補

  • QRasterizer: 高速なラスターグラフィック描画機能を提供するライブラリです。より複雑な形状やアニメーションを描く場合は、QPainterよりも高速に処理できる可能性があります。
  • QPainter::drawPath(): パスオブジェクトを使用して、様々な形状を描くための関数です。drawPolyline()よりも柔軟な表現が可能で、曲線なども描くことができます。
  • QPainter::drawLine(): 2点間の直線を引くための関数です。シンプルな線を描く場合は、drawPolyline()よりも効率的に処理できます。

選択の指針

以下の点を考慮して、適切な代替手段を選択してください。

  • コードの簡潔性: シンプルな線を描く場合は、QPainter::drawLine()が最も簡潔なコードで実現できます。
  • 表現力: より複雑な形状や表現が必要な場合は、QPainter::drawPath()などの関数を検討する必要があります。
  • パフォーマンス: より高速な描画が必要な場合は、QRasterizerなどのライブラリを検討する必要があります。
  • 描画する形状: 描きたい形状によって、適切な関数は異なります。

以下の例は、QPainter::drawLine()QPainter::drawPath()を使用して、QPainter::drawPolyline()と同等の描画を行う方法を示しています。

例1:QPainter::drawLine()を使用した三角形の描画

#include <QApplication>
#include <QWidget>
#include <QPainter>

class MyWidget : public QWidget {
public:
    MyWidget() {
        setWindowTitle("三角形を描く");
        setFixedSize(200, 150);
    }

protected:
    void paintEvent(QPaintEvent *event) override {
        QPainter painter(this);

        // 線の太さを設定
        painter.setPen(QPen(Qt::red, 2));

        // 3つの線を描画して三角形を描く
        painter.drawLine(QPoint(10, 20), QPoint(50, 80));
        painter.drawLine(QPoint(50, 80), QPoint(90, 20));
        painter.drawLine(QPoint(90, 20), QPoint(10, 20));
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    MyWidget widget;
    widget.show();
    return app.exec();
}
#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QPainterPath>

class MyWidget : public QWidget {
public:
    MyWidget() {
        setWindowTitle("五角形を描く");
        setFixedSize(250, 200);
    }

protected:
    void paintEvent(QPaintEvent *event) override {
        QPainter painter(this);

        // パスオブジェクトを作成
        QPainterPath path;
        path.moveTo(50, 30);
        path.lineTo(100, 60);
        path.lineTo(150, 30);
        path.lineTo(130, 100);
        path.lineTo(80, 100);
        path.close();

        // 線の太さを設定
        painter.setPen(QPen(Qt::blue, 3));

        // パスを使用して五角形を描画
        painter.drawPath(path);
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    MyWidget widget;
    widget.show();
    return app.exec();
}