Qt 2D 描画: 基本的なグラフィック描画とグラデーション塗りつぶし

Qt は、同じ API を使用して画面や描画デバイスに描画できる強力な 2D 描画システムを提供しており、主に QPainter、QPaintDevice、QPaintEngine の 3 つのクラスに基づいています。それらの関係を次の図に示します。

  • QPainter は描画操作を実行するために使用されます。
  • QPaintEngine は、QPainter がさまざまなデバイス上で描画するために使用できるいくつかのインターフェイスを提供します。
  • QPaintDevice は、QPainter を使用して描画できる 2 次元空間の抽象化である描画デバイスを提供します。

特定の描画操作は描画システムの QPainter によって実行されます。QPainter は、GUI プログラミングに必要な描画作業のほとんどを完了するための高度に最適化された機能を多数提供します。QPainter は、最も単純な直線からその他の複雑なグラフィックまで、あらゆる必要なグラフィックを描画することができ、テキストや絵を描画するために使用することもできます。QPainter は、QPaintDevice クラスを継承する任意のオブジェクトに描画できます。

QPainterは通常、コンポーネント再描画イベント(PaintEvent)の処理関数paintEvent()で描画し、最初にQPainterオブジェクト(ブラシ)を作成し、次にグラフィックを描画し、最後にQPainterオブジェクトを破棄します。

1. 基本的なグラフィックスの描画

QPainterにはよく使うグラフィックを描画するための便利な機能がいくつか用意されており、線や枠線用のブラシや塗りつぶし用のブラシを設定することもできます。

新しい Qt Gui アプリケーションを作成します。プロジェクト名は myDrawing、基本クラスは QWidget、クラス名は Widget です。確立が完了したら、widget.h ファイルで再描画イベント ハンドラー関数を宣言します。

protected:
    void paintEvent(QPaintEvent *);

次に、ヘッダー ファイル #include <QPainter> を widget.cpp ファイルに追加します。

この記事のメリット、Qt 開発学習教材パッケージの受け取り料金、技術ビデオ、コンテンツには (C++ 言語基礎、Qt プログラミング入門、QT シグナルとスロットのメカニズム、QT インターフェイス開発イメージ図、QT ネットワーク、QT データベース プログラミング、QT プロジェクト戦闘、QSS、OpenCV、Quick モジュール、インタビューの質問など) ↓↓↓↓↓↓ 下記を参照

1.1 グラフィックの描画

widget.cpp ファイルで、paintEvent() 関数を次のように定義します。

void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    //绘制线条
    painter.drawLine(QPoint(0, 0), QPoint(100, 100));
}

ここでは、QPainter::QPainter(QPaintDevice *device) コンストラクターを使用して QPainter オブジェクトが最初に作成され、これを描画デバイスとして指定します。これはパーツ上に描画することを意味します。このコンストラクターを使用して作成されたオブジェクトは、デバイス上で直ちに描画を開始し、自動的に begin() 関数を呼び出してから、QPainter デストラクターの end() 関数を呼び出して描画を終了します。

QPainter オブジェクトの構築時に描画デバイスを指定したくない場合は、パラメーターなしでコンストラクターを使用し、描画開始時に QPainter::begin (QPaintDevice *device) を使用して描画デバイスを指定し、描画が完了した後に end() 関数を呼び出して描画を終了します。上記の関数のコードは次と同等です。

QPainter painter;
painter.begin(this);
painter.drawLine(QPoint(0, 0), QPoint(100, 100));
painter.end();

この 2 つの方法で描画を完了できますが、どちらの方法を使用しても描画デバイスを指定しないと描画できません。コードの 2 行目では、drawLine() 関数を使用して線分を描画します。ここでは、関数 QPainter::drawLine ( const QPoint & p1, const QPoint & p2 ) のオーバーロードされた形式が使用されており、p1 と p2 はそれぞれ線分の始点と終点です。ここでの QPoint(0, 0) はウィンドウの原点であり、デフォルトはウィンドウの左上隅 (タイトル バーを除く) です。結果は以下の通り。

 

QPainter は、単純な線の描画に加えて、その他の一般的に使用されるグラフィックを描画するための関数もいくつか提供しています。最も一般的に使用される関数を次の表に示します。

関数

関数

描画アーク()

弧を描く

ドローコード()

ひもを引く

drawConvexPolygon()

凸多角形を描く

描画楕円()

楕円を描く

描画ライン()

線を描く

ドローパイ()

描画セクター

ドローポイント()

ドローポイント

描画ポリゴン()

多角形を描く

描画ポリライン()

ポリラインを描く

描画Rect()

長方形を描く

drawRoundedRect()

角丸長方形を描く

さらに、QPainter クラス名にカーソルを置き、キーボードの F1 ボタンを押すと、このクラスのヘルプ ページに自動的にジャンプします。もちろん、ヘルプ モードに移動して直接インデックスを作成してクラス名を見つけることもできます。ヘルプには、次の図に示すように、関連する描画関数が多数表示されます。

 

関数名をクリックするとその関数の紹介文へジャンプします。たとえば、drawEllipse() 関数をクリックすると、関数の紹介にジャンプします。上に例が示されています。以下に示すように。例のコードをpaintEvent()関数に直接コピーして、効果をテストできます。

 

1.2 ブラシの使用

QPen は、QPainter が線や輪郭を描く方法を定義します。ブラシには、スタイル style()、幅 width()、ブラシ Brush()、キャップ スタイル capStyle()、接続スタイル joinStyle() などのプロパティがあります。まず、QPen クラスのコンストラクターを導入します。

QPen(const QBrush &brush, qreal width, Qt::PenStyle s = Qt::SolidLine,
         Qt::PenCapStyle c = Qt::SquareCap, Qt::PenJoinStyle j = Qt::BevelJoin);
  • ブラシ Brush() は、ブラシで描かれた線を塗りつぶすために使用されます。
  • ブラシ スタイル style() は線のスタイルを定義します。
  • ペンキャップスタイルの capStyle() は、QPainter で描画される線の終端を定義します。
  • 接続スタイル joinStyle() は、2 つの線がどのように接続されるかを定義します。
  • ブラシの幅 width() または widthF() はブラシの幅を定義します。幅が 0 の線はないことに注意してください。幅を 0 に設定すると、QPainter は引き続き線を描画し、この線の幅は 1 ピクセルになります。

非常に多くのパラメータを構築時に指定できるか、set 関数で指定できるかは完全にユーザーの習慣に依存します。setWidth()、setBrush()、setCapStyle()、setJoinStyle() 関数を使用して、さまざまな設定を簡単に変更できます。

ブラシスタイル

 

次に、paintEvent() 関数の内容を次のように変更します。

void Widget::paintEvent(QPaintEvent *)
{
    //创建画笔
    QPen pen(Qt::green, 5, Qt::DotLine, Qt::RoundCap, Qt::RoundJoin);
    //使用画笔绘制圆弧
    painter.setPen(pen);
    QRectF rectangle(70.0, 40.0, 80.0, 60.0);
    int startAngle = 30 * 16;
    int spanAngle = 120 * 16;
    painter.drawArc(rectangle, startAngle, spanAngle);
}

上記のブラシを作成した後、setPen() を使用してペインター用のブラシを設定し、そのブラシを使用して円弧を描きます。描画円弧関数のオーバーロード形式は QPainter::drawArc ( const QRectF & Rectangle, int startAngle, int spanAngle ) です。以下の図に示すように、3 つのパラメーターは円弧を指定する必要がある長方形、開始角度、およびスパン角度に対応します。

QRectF:: QRectF (qreal x、qreal y、qreal width、qreal height) は、浮動小数点数をパラメーターとして使用して四角形を決定できます。四角形には、左上隅の座標 (x、y)、幅、および高さを指定する必要があります。整数を使用して四角形を定義したいだけの場合は、QRect クラスを使用できます。ここでの角度の値は、実際の度に 16 を掛けたものです。時計の文字盤では、0 度は 3 時の位置を指します。角度の値が正の場合は反時計回りの回転を意味します。角度の値が負の場合は時計回りの回転を意味します。円全体の値は 5760 (つまり 360X16) です。

 

1.3 ブラシの使用

QBrush クラスは、グラフィックスを塗りつぶすためのブラシを提供します。ブラシは、その色とスタイル (塗りつぶしモードなど) を使用して定義されます。まず、QBrush クラスのコンストラクターを導入します。

QBrush(const QColor &color, Qt::BrushStyle bs=Qt::SolidPattern);

Qt で使用される色は通常、RGB、HSV、CMYK などのカラー モデルをサポートする QColor クラスによって表されます。パラメーターが 3 つある場合、それらは赤、緑、青のコンポーネントの値 (通常は rgb と呼ばれます) であり、値の範囲は 0 ~ 255 です。たとえば、ここで (255, 0, 0) は、赤のコンポーネントが 255 で、他のコンポーネントが 0 であることを意味するため、出力は赤になります。パラメータが 4 つある場合、最後のパラメータ alpha は透明度を設定するもので、値の範囲も 0 ~ 255 で、0 は完全に透明、255 は完全に不透明を意味します。以下の図に示すように、Qt には 20 の事前定義された色もあります。

 

QBrush スタイルの塗りつぶしモードは、基本的なパターン塗りつぶし、グラデーション塗りつぶし、テクスチャ塗りつぶしを含む Qt::BrushStyle 列挙型変数によって定義されます。すべての列挙型変数は次の図に示されています。デフォルトのスタイルは Qt::NoBrush (ブラシの作成方法に応じて異なります) で、形状を塗りつぶしません。標準の塗りつぶしスタイルは Qt::SolidPattern です。ブラシスタイルを設定するには、コンストラクターを使用する方法と setstyle 関数を使用する方法の 2 つがあります。

 

次に、paintEvent() 関数の内容を次のように変更します。

void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QPen pen; //画笔
    pen.setColor(QColor(255, 0, 0));
    QBrush brush(QColor(0, 255, 0, 125)); //画刷
    painter.setPen(pen); //添加画笔
    painter.setBrush(brush); //添加画刷
    painter.drawRect(50, 50, 200, 100); //绘制矩形
}

ここではブラシQPenとブラシQBrushを新規作成します。このうち、ブラシは setColor() 関数を使用して色を設定します。ブラシはビルド時に直接設定された色です。次に、ペンとブラシをペインタに設定し、drawRect() を使用して、左上隅が (50, 50) にあり、幅 200、高さ 100 の長方形を描画します。プログラムを実行すると、その効果が次の図に示されます。

 

2. グラデーション塗りつぶし

グラデーション塗りつぶしはブラシでも使用できます。QGradient クラスは、QBrush でグラデーション塗りを指定するために使用されます。Qt は 3 種類のグラデーション塗りつぶしをサポートするようになりました。

  • 線形グラデーションは、開始点と終了点の間で色を補間します。
  • 放射状グラデーションは、焦点とその周囲のリングの間で色を補間します。
  • 円錐形のグラデーション (Conical) は、円の中心の周りで色を補間します。

これら 3 つのグラデーションは、QGradient の 3 つのサブクラスで表されます。QLinearGradient は線形グラデーションを表し、QRadialGradient は放射状グラデーションを表し、QConicalGradient は円錐形グラデーションを表します。

(1) 線形勾配

QLinearGradient::QLinearGradient ( const QPointF & start, const QPointF & finalStop )

線形グラデーションでは、始点 Start終点 Finalstopを指定し、始点と終点の間の領域を均等にする必要があります。始点の位置は 0.0、終点の位置は 1.0 です。それらの間の位置は距離比で設定され、QGRADIENT :: Setcolorat (QREAL POSITION, Const QCOLORJ & The color) 関数を使用します。指定された位置の指定された色 color になります。もちろん、ここでの位置は 0 から 1 の間です

ここで setSpread() 関数を使用して塗りつぶし拡散方法を設定することもできます。つまり、指定した領域以外の領域をどのように塗りつぶすかを指定できます。スプレッド方法は、合計 3 つの値を持つ QGradient::Spread 列挙変数によって定義されます。すなわち、デフォルト値である最も近い色で塗りつぶされる QGradiem::PadSpread、QGradient::ReflectSpread はグラデーション領域の外側のグラデーションを反映します、QGradiem::RepeatSpread はグラデーション領域の外側のグラデーションを繰り返します。グラデーション塗りつぶしを使用するには、setBrush() で直接使用できます。そうすると、ブラシ スタイルが対応するグラデーション塗りつぶしに自動的に設定されます。線形勾配におけるこれら 3 つの拡散法の効果を下の図に示します。

 

(2) 放射勾配

QRadialGradient::QRadialGradient ( const QPointF & center, qreal radius, const QPointF & focalPoint )

放射状グラデーションでは、円の中心と半径を指定する必要があるため、円が決定され、焦点が指定されます。フォーカスの位置を 0、リングの位置を 1 として、フォーカスとリングの間で色が補間されます。放射線勾配は、setSpread() 関数を使用して、勾配領域の外側の領域の拡散モードを設定することもできます。3 つの拡散モードの効果を次の図に示します。

 

(3) 円錐形の勾配

QConicalGradient::QConicalGradient ( const QPointF & center, qreal angle )

テーパー グラデーションでは、中心点の中心と角度 (値は 0 ~ 360) を指定し、指定された角度から反時計回りに中心点の周囲の色の補間を開始する必要があります。ここで与えられる角度は、反時計回り方向の開始時が 0、1 回転後に 1 になります。setSpread() 関数は、テーパード グラデーションには影響しません。

(4) サンプルプログラム

サンプルプログラムは以下のとおりです。

void Widget::paintEvent(QPaintEvent *)
{
    //线性渐变
    QLinearGradient linearGradient(QPointF(40, 190),QPointF(70, 190));
    //插入颜色
    linearGradient.setColorAt(0, Qt::yellow);
    linearGradient.setColorAt(0.5, Qt::red);
    linearGradient.setColorAt(1, Qt::green);
    //指定渐变区域以外的区域的扩散方式
    linearGradient.setSpread(QGradient::RepeatSpread);
    //使用渐变作为画刷
    QPainter painter(this);
    painter.setBrush(linearGradient);
    painter.drawRect(100, 100, 90, 40);

    //辐射渐变
    QRadialGradient radialGradient(QPointF(100, 190),50,QPointF(275,200));
    radialGradient.setColorAt(0, QColor(255, 255, 100, 150));
    radialGradient.setColorAt(1, QColor(0, 0, 0, 50));
    painter.setBrush(radialGradient);
    painter.drawEllipse(QPointF(100, 200), 50, 50);

    //锥形渐变
    QConicalGradient conicalGradient(QPointF(250, 190), 60);
    conicalGradient.setColorAt(0.2, Qt::cyan);
    conicalGradient.setColorAt(0.9, Qt::black);
    painter.setBrush(conicalGradient);
    painter.drawEllipse(QPointF(250, 200), 50, 50);
}

プログラムを実行すると、次のような効果が得られます。

ブログガーデン(fengMisaka)から記事を転載しました:Qt 2D描画その1:基本的なグラフィック描画とグラデーション塗りつぶし

この記事のメリット、Qt 開発学習教材パッケージの受け取り料金、技術ビデオ、コンテンツには (C++ 言語基礎、Qt プログラミング入門、QT シグナルとスロットのメカニズム、QT インターフェイス開発イメージ図、QT ネットワーク、QT データベース プログラミング、QT プロジェクト戦闘、QSS、OpenCV、Quick モジュール、インタビューの質問など) ↓↓↓↓↓↓ 下記を参照

おすすめ

転載: blog.csdn.net/QtCompany/article/details/131816784