Qt GUI 描画の基礎:QPainter::y をマスターして 2D 描画を自在に操る
座標指定
- 例えば、
(x, y)
座標に点を描画したい場合はQPainter::drawPoint(x, y)
を、(x1, y1)
から(x2, y2)
までの直線を描画したい場合はQPainter::drawLine(x1, y1, x2, y2)
を使用します。 QPainter::moveTo(x, y)
やQPainter::lineTo(x, y)
などの関数で使用し、描画の開始点や終点、中間点を指定することができます。
変換処理
- 例えば、描画対象を
(50, 100)
だけ右方向に移動したい場合はQPainter::translate(50, 0)
を、下方向に移動したい場合はQPainter::translate(0, 100)
を使用します。 QPainter::translate(x, y)
関数を使用して、描画対象全体を(x, y)
だけ平行移動する場合に役立ちます。
- 単位: ピクセル単位で指定されます。
- 座標系: Y軸は上向きに増加します。
- 原点: Qt GUIにおける原点は、ウィンドウの左上角です。
// (100, 50) 座標に赤い点を描画
QPainter painter(widget);
painter.setPen(Qt::red);
painter.drawPoint(100, 50);
// (20, 80) から (180, 80) までの緑色の線を描画
painter.setPen(Qt::green);
painter.drawLine(20, 80, 180, 80);
// 描画対象を (50, 100) だけ平行移動
painter.translate(50, 100);
// (150, 150) 座標に青い四角形を描画
painter.setBrush(Qt::blue);
painter.drawRect(150, 150, 100, 100);
- 描画に関するより高度な機能については、Qtドキュメントの
QPainter
クラスに関するセクションを参照してください。 - QPainter::y以外にも、
QPainter::x
を使用して水平方向の位置を指定することができます。
点と線
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPainter>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QLabel label;
label.resize(300, 200);
QPainter painter(&label);
painter.setPen(Qt::red);
// (50, 100) に赤い点を描画
painter.drawPoint(50, 100);
// (20, 30) から (180, 30) までの緑色の線を描画
painter.setPen(Qt::green);
painter.drawLine(20, 30, 180, 30);
label.show();
return app.exec();
}
このコードを実行すると、赤い点と緑色の線が描かれたウィンドウが表示されます。
四角形
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPainter>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QLabel label;
label.resize(300, 200);
QPainter painter(&label);
painter.setPen(Qt::black);
painter.setBrush(Qt::blue);
// (100, 100) に青い四角形を描画
painter.drawRect(100, 100, 100, 100);
label.show();
return app.exec();
}
このコードを実行すると、青い四角形が描かれたウィンドウが表示されます。
円
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPainter>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QLabel label;
label.resize(300, 200);
QPainter painter(&label);
painter.setPen(Qt::black);
painter.setBrush(Qt::yellow);
// (150, 100) 中心、半径 50 の黄色い円を描画
painter.drawEllipse(150, 100, 50, 50);
label.show();
return app.exec();
}
このコードを実行すると、黄色い円が描かれたウィンドウが表示されます。
楕円
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPainter>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QLabel label;
label.resize(300, 200);
QPainter painter(&label);
painter.setPen(Qt::black);
painter.setBrush(Qt::magenta);
// (100, 150) 中心、横幅 80、縦幅 40 のマゼンタ色の楕円を描画
painter.drawEllipse(100, 150, 80, 40);
label.show();
return app.exec();
}
このコードを実行すると、マゼンタ色の楕円が描かれたウィンドウが表示されます。
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPainter>
#include <QPainterPath>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QLabel label;
label.resize(300, 200);
QPainter painter(&label);
painter.setPen(Qt::red);
QPainterPath path;
path.moveTo(50, 50);
path.quadraticCurveTo(150, 50, 150, 150);
path.quadraticCurveTo(50, 150, 50, 50);
painter.drawPath(path);
QPoint 構造体
- 例:
- 欠点:
- QPainter::y 単体よりも記述量が増加します。
QPoint point(100, 50); // (100, 50) 座標を QPoint 構造体に格納
// 点を描画
painter.drawPoint(point);
// 線を描画
painter.drawLine(point1, point2);
QPointF 構造体
- 例:
- 欠点:
- QPainter::y や QPoint 構造体よりも記述量が増加します。
- 利点:
- 小数点を含む座標値を扱えるため、より精度の高い描画が可能です。
- 将来的に小数点座標が必要になる可能性を考慮した予防策として有効です。
QPointF pointF(50.5, 100.25); // (50.5, 100.25) 座標を QPointF 構造体に格納
// 点を描画
painter.drawPoint(pointF);
// 線を描画
painter.drawLine(pointF1, pointF2);
変数
- 例:
- 欠点:
- コードの意味を把握しにくくなる場合があり、保守性が低下する可能性があります。
- 変数名が分かりにくいと、意図が伝わりにくくなります。
- 利点:
- 非常に簡潔な記述が可能で、コードの見やすさが向上します。
- 計算結果などを直接座標値として利用できます。
int x = 150;
int y = 200;
// 点を描画
painter.drawPoint(x, y);
// 線を描画
painter.drawLine(x1, y1, x2, y2);
- 座標変換行列を用いた描画
- 極座標を用いた描画
- 一般的には、QPainter::y を基本とし、状況に応じて代替方法を検討することをおすすめします。
- 可読性、コードの簡潔性、保守性、描画精度などを考慮しましょう。
- 描画対象や目的に応じて、適切な方法を選択することが重要です。
- 例えば、ループ処理などで動的に座標値を生成する場合には、関数やラムダ式などを組み合わせて柔軟に対応することができます。
- 上記以外にも、状況によってはより高度なテクニックを用いることもできます。