座標系
座標系は、QPainter クラスによって制御されます。QPaintDevice およびQPaintEngine クラスと併せて、QPainter は Qt の描画システム「Arthur」の基盤を形成しています。QPainter は描画操作を実行するために使用され、QPaintDevice は、QPainter を使用して描画できる 2 次元空間の抽象化であり、QPaintEngine は、ペインターがさまざまな種類のデバイスに描画するために使用するインターフェースを提供します。
QPaintDevice クラスは、描画可能なオブジェクトの基底クラスです。その描画機能は、QWidget 、QImage 、QPixmap 、QPicture 、およびQOpenGLPaintDevice クラスに継承されています。ペイントデバイスのデフォルトの座標系の原点は左上隅にあります。x値は右に向かうにつれて増え、y値は下に向かうにつれて増えます。デフォルトの単位は、ピクセルベースのデバイスでは 1 ピクセル、プリンタでは 1 ポイント(1 インチの 72 分の 1)です。
論理座標QPainter から物理座標QPaintDevice へのマッピングは、QPainter の変換行列、ビューポート、および「ウィンドウ」によって処理されます。デフォルトでは、論理座標系と物理座標系は一致しています。QPainter は、座標変換(回転やスケーリングなど)もサポートしています。
レンダリング
論理的な表現
グラフィックスプリミティブのサイズ(幅と高さ)は、レンダリングに用いられるペンの幅を無視して、常にその数学的モデルに対応します:
| QRect(QPoint(1, 2),QPoint(7, 6)) | QLine(QPoint(2, 7),QPoint(6, 1)) |
| QLine(2, 7, 6, 1) | |
| QRect(QPoint(1, 2),QSize(6, 4)) | |
| QRect(1, 2, 6, 4) |
エイリアシングペインティング
描画時、ピクセルのレンダリングは `QPainter::Antialiasing ` レンダリングヒントによって制御されます。
RenderHint 列挙型は、QPainter に対してフラグを指定するために使用されますが、そのフラグが特定のエンジンによって尊重されるかどうかは保証されません。QPainter::Antialiasing 値は、可能であればエンジンがプリミティブのエッジにアンチエイリアス処理を行うべきであることを示します。つまり、色の濃淡を用いてエッジを滑らかにする処理です。
しかし、デフォルトではペインターにはエイリアシングが発生し、他のルールが適用されます。幅1ピクセルのペンでレンダリングする場合、ピクセルは数学的に定義された点の右側および下側にレンダリングされます。例えば:
ピクセル数が偶数のペンで描画する場合、ピクセルは数学的に定義された点を中心に左右対称に描画されますが、ピクセル数が奇数のペンで描画する場合、余分な1ピクセルは、1ピクセル幅の場合と同様に、数学的に定義された点の右側および下側に描画されます。具体的な例については、以下の「QRectF 」の図を参照してください。
| QRectF | |
|---|---|
![]() | ![]() |
| 論理的な表現 | 幅1ピクセルのペン |
![]() | ![]() |
| 2ピクセル幅のペン | 3ピクセル幅のペン |
なお、歴史的な理由により、QRect::right() およびQRect::bottom() 関数の戻り値は、矩形の真の右下隅とは異なります。
QRect right() 関数は () + () - 1 を返し、 () 関数は () + () - 1 を返します。図中の右下の緑色の点は、これらの関数の戻り座標を示しています。left width bottom top height
代わりに、QRectF を使用することをお勧めします。QRectF クラスは、精度を確保するために浮動小数点座標を使用して平面上の矩形を定義しており(QRect は整数座標を使用します)、QRectF::right()およびQRectF::bottom()関数は、真の右下隅を返します。
あるいは、QRect を使用し、x() +width() およびy() +height() を適用して右下隅を求め、right() およびbottom() 関数の使用を避けてください。
アンチエイリアス処理
QPainter のanti-aliasing レンダリングヒントを設定すると、ピクセルは数学的に定義された座標の両側で対称的にレンダリングされます:
変換
デフォルトでは、QPainter は関連付けられたデバイス独自の座標系上で動作しますが、アフィン座標変換も完全にサポートしています。
QPainter::scale() 関数を使用して座標系を所定のオフセット分スケールしたり、QPainter::rotate() 関数を使用して時計回りに回転させたり、QPainter::translate() 関数を使用して並進(つまり、座標に所定のオフセットを加える)させたりすることができます。
また、QPainter::shear() 関数を使用して、原点を中心に座標系をねじることができます。すべての変換操作は、QPainter の変換行列に対して行われます。この行列は、QPainter::worldTransform() 関数を使用して取得できます。行列は、平面上の1つの点を別の点に変換します。
同じ変換を繰り返し行う必要がある場合は、QTransform オブジェクトやQPainter::worldTransform()、QPainter::setWorldTransform()関数を使用することもできます。QPainter::save()関数を呼び出すことで、いつでもQPainter の変換行列を内部スタックに保存できます。QPainter::restore()関数でそれをスタックから取り出すことができます。
変換行列が頻繁に必要となるのは、さまざまな描画デバイスで同じ描画コードを再利用する場合です。変換を行わないと、結果は描画デバイスの解像度に強く縛られてしまいます。プリンタは600ドット/インチといった高解像度であるのに対し、画面の解像度は多くの場合72~100ドット/インチです。
| アナログ時計の例 | |
|---|---|
![]() | 「アナログ時計」の例では、QPainter の変換行列を使用して、カスタムウィジェットの内容を描画する方法を示しています。 読み進める前に、このサンプルをコンパイルして実行することをお勧めします。特に、ウィンドウのサイズをさまざまな大きさに変更してみてください。 |
座標系を、点 (0, 0) がウィジェットの左上隅ではなく、中心に来るように平行移動させます。 また、座標系を これにより、中心に原点 (0, 0) を持つ 200 × 200 の正方形の領域が得られ、そこに描画を行うことができます。描画された内容は、ウィジェット内に収まる最大の正方形の中に表示されます。 「ウィンドウとビューポートの変換」のセクションも参照してください。 座標系を回転させ、QPainter::drawConvexPolygon() を呼び出すことで、時計の時針を描画します。回転処理を行うことで、時針は正しい方向を指すように描画されます。 多角形は、x 座標とy座標が交互に並ぶ配列として指定され、関数の冒頭で定義された静的変数 コードを囲むQPainter::save()およびQPainter::restore()の呼び出しにより、その後のコードが、これまでに行った変換の影響を受けないことが保証されます。 その後、時計の文字盤の時刻マーカーを描画します。これは、30度間隔で配置された12本の短い線で構成されています。このループが終了すると、ペインターは1周回転して元の状態に戻っているため、状態を保存したり復元したりする必要はありません。 時計の分針についても同様の処理を行います。分針は、3つの点 (7, 8)、(-7, 8)、(0, -70) で定義されます。これらの座標は、分針よりも細く長い針を指定しています。 最後に、時計の文字盤の分目盛りを描画します。これは、6度間隔で60本の短い線で構成されています。 時間目盛りの上に描画してしまわないように、5つおきの分目盛りを省略します。その処理の最後に、ペインターは実用的な回転とは言い難い方向に回転されますが、描画自体は完了しているため、問題にはなりません。 | |
変換行列の詳細については、QTransform のドキュメントを参照してください。
ウィンドウとビューポートの変換
QPainter を使用して描画する場合、論理座標を使用して点を指定し、それがペイントデバイスの物理座標に変換されます。
論理座標から物理座標へのマッピングは、QPainter のワールド変換関数 `worldTransform()`(「変換」のセクションで説明)およびQPainter の `viewport()` および `window()` によって処理されます。ビューポートは、任意の長方形を指定する物理座標を表します。 「ウィンドウ」は、論理座標系における同じ矩形を表します。デフォルトでは、論理座標系と物理座標系は一致しており、ペイントデバイスの矩形と同等です。
ウィンドウとビューポートの変換を利用することで、論理座標系を好みに合わせて調整できます。 この仕組みを利用すれば、描画コードをペイントデバイスから独立させることも可能です。例えば、QPainter::setWindow() 関数を呼び出すことで、論理座標を (-50, -50) から (50, 50) まで(中心を (0, 0) とする)に拡張することができます:
これで、論理座標 (-50, -50) は、描画デバイスの物理座標 (0, 0) に対応するようになります。描画デバイスに依存することなく、描画コードは常に指定された論理座標上で動作します。
「ウィンドウ」またはビューポートの矩形を設定することで、座標の線形変換が行われます。なお、「ウィンドウ」の各隅はビューポートの対応する隅に写像され、その逆も同様であることに注意してください。そのため、変形を防ぐために、通常はビューポートと「ウィンドウ」のアスペクト比を同じに保つことが推奨されます:
int side = qMin(width(), height());
int x = (width() - side / 2);
int y = (height() - side / 2);
painter.setViewport(x, y, side, side);論理座標系を正方形にする場合は、QPainter::setViewport() 関数を使用して、ビューポートも正方形にする必要があります。 上記の例では、ペイントデバイスの長方形に収まる最大の正方形と等価になるようにしています。ウィンドウやビューポートを設定する際にペイントデバイスのサイズを考慮することで、描画コードをペイントデバイスに依存させずに保つことが可能になります。
なお、ウィンドウからビューポートへの変換は単なる線形変換であり、クリッピングは行われない点に注意してください。つまり、現在設定されている「ウィンドウ」の外側に描画した場合でも、その描画結果は同じ線形代数的手法を用いてビューポートに変換されます。
ビューポート、「ウィンドウ」、および変換行列によって、QPainter の論理座標がペイントデバイスの物理座標にどのようにマッピングされるかが決まります。 デフォルトでは、ワールド変換行列は単位行列であり、「ウィンドウ」とビューポートの設定はペイントデバイスの設定と同等です。つまり、ワールド座標系、「ウィンドウ」座標系、およびデバイス座標系は同等ですが、これまで見てきたように、これらの座標系は変換演算やウィンドウ-ビューポート変換を用いて操作することができます。 上の図はこのプロセスを説明しています。
「アナログ時計」も参照してください 。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.








