転載:https://wizardforcel.gitbooks.io/qt-beginning/content/22.html
はじめに
前のセクションでは、簡単なグラフィティボードの実装方法について説明しましたが、今回は、グラフィティボードに描画グラフィックスを実装します。ここでは、例として長方形を使用します。ダブルバッファドローイングの概念については後で説明します。
環境:Windows Xp + Qt 4.8.4 + QtCreator 2.6.2
ディレクトリ
- まず、長方形を描きます
- 2、ダブルバッファドローイング
テキスト
まず、長方形を描きます
1。前のプログラムに基づいてまだ変更しpainEvent()
ます。最初に関数を変更します。
-
void Dialog::paintEvent(QPaintEvent *)
-
{
-
QPainter painter(this);
-
int x,y,w,h;
-
x = lastPoint.x();
-
y = lastPoint.y();
-
w = endPoint.x() - x;
-
h = endPoint.y() - y;
-
painter.drawRect(x, y, w, h);
-
}
ここでは、lastPointとendPointの点を通過して描画される長方形の開始点、幅、高さを決定します。プログラムを実行し、マウスで長方形をドラッグします。効果は下図に示されています。
2。長方形は上からドラッグできますが、この方法でウィンドウに直接描くことができます。以前に描いた長方形は保存できません。下にキャンバスを追加して、キャンバスに描画します。paintEvent()
この関数は、以下のように変更します。
-
void Dialog::paintEvent(QPaintEvent *)
-
{
-
int x,y,w,h;
-
x = lastPoint.x();
-
y = lastPoint.y();
-
w = endPoint.x() - x;
-
h = endPoint.y() - y;
-
QPainter pp(&pix);
-
pp.drawRect(x, y, w, h);
-
QPainter painter(this);
-
painter.drawPixmap(0, 0, pix);
-
}
ここでは、まずキャンバスにグラフィックスを描画し、次にキャンバスをウィンドウに描画します。プログラムを実行してから、マウスを使用して四角形をドラッグし、幽霊がたくさんあることを発見しました。効果を以下に示します。
なぜそのような現象があるのですか?マウスをドラッグすることで長方形をすばやく、マウスをドラッグすることでゆっくりと長方形を描くことができます。その結果、ドラッグ速度が速いほどゴーストが少なくなります。実際、マウスをドラッグする過程で画面が何度もリフレッシュされており、paintEvent()
関数が何度も実行され、実行されるたびに長方形が描かれていることもわかります。その理由を知って、この問題を回避する方法があります。
2、ダブルバッファドローイング
1。別の補助キャンバスを追加します。描画している場合、つまり、マウスボタンが離されていない場合は、この補助キャンバスに描画します。マウスボタンが離されたときのみ、実際のキャンバスに描画します。
まずdialog.h
、2つのプライベート変数をファイルに追加します。
-
QPixmap tempPix; //辅助画布
-
bool isDrawing; //标志是否正在绘图
次にdialog.cpp
、コンストラクターで変数を初期化します。
isDrawing = false;
次に、paintEvent()
関数を変更します。
-
void Dialog::paintEvent(QPaintEvent *)
-
{
-
int x,y,w,h;
-
x = lastPoint.x();
-
y = lastPoint.y();
-
w = endPoint.x() - x;
-
h = endPoint.y() - y;
-
QPainter painter(this);
-
if(isDrawing) //如果正在绘图,就在辅助画布上绘制
-
{
-
//将以前pix中的内容复制到tempPix中,保证以前的内容不消失
-
tempPix = pix;
-
QPainter pp(&tempPix);
-
pp.drawRect(x,y,w,h);
-
painter.drawPixmap(0, 0, tempPix);
-
} else {
-
QPainter pp(&pix);
-
pp.drawRect(x,y,w,h);
-
painter.drawPixmap(0,0,pix);
-
}
-
}
また、マウスダウンイベントハンドラーとマウスリリースイベントハンドラーの内容を変更する必要もあります。
-
void Dialog::mousePressEvent(QMouseEvent *event)
-
{
-
if(event->button()==Qt::LeftButton) //鼠标左键按下
-
{
-
lastPoint = event->pos();
-
isDrawing = true; //正在绘图
-
}
-
}
-
void Dialog::mouseReleaseEvent(QMouseEvent *event)
-
{
-
if(event->button() == Qt::LeftButton) //鼠标左键释放
-
{
-
endPoint = event->pos();
-
isDrawing = false; //结束绘图
-
update();
-
}
-
}
マウスの左ボタンを押すと、図面のマーキングが開始され、ボタンを放すと、図面のマーキングがキャンセルされます。ここでプログラムを実行すると、通常の描画を行うことができます。効果を以下に示します。
2。ダブルバッファドローイング
この例で使用されている手法に基づいて、いわゆるダブルバッファドローイングの概念を紹介します。ダブルバッファ(ダブルバッファ)描画、つまり、描画する場合、すべてのコンテンツが描画デバイス(などQPixmap
)に描画され、次に画像全体がパーツに描画されて表示されます。ダブルバッファ描画を使用すると、表示中のちらつきを回避できます。Qt 4.0以降、QWidget
パーツのすべての描画は自動的にダブルバッファリングpaintEvent()
を使用するため、通常、関数でダブルバッファリングコードを使用してちらつきを回避する必要はありません。
一般的な描画では手動でダブルバッファ描画を使用する必要はありませんが、描画効果を実現するには、ダブルバッファの概念に依存する必要があります。たとえば、このプログラムでは、マウスを使用して、インターフェイス上に任意のサイズの長方形を描画します。ここでは2つのキャンバスが必要ですが、どちらもQPixmap
例です。1つはtempPix
一時バッファーとして使用されます。マウスで長方形をドラッグして描画すると、コンテンツが最初に描画tempPix
さtempPix
れてからインターフェイスに描画され、もう1つはpix
バッファーとして使用されます、完成した図面を保存するために使用されます。マウスtempPix
を離して長方形の描画を完了すると、コンテンツがpixにコピーされます。描画時にスミアを表示せず、以前に描画されたコンテンツが消えないようにするために、マウスの移動中に描画tempPix
するたびに、長方形の元の画像に描画する必要があるため、毎回描画する必要があります。まず、pixのコンテンツをコピーしますtempPix
。ここには2つのQPixmap
オブジェクトがあるため、バッファが2つあると言え、ダブルバッファドローイングと呼ばれます。
おわりに
Qtの基本的な描画の内容については、ここで説明しますが、これらの基本的な知識をより体系的かつ詳細に学習したい場合は、「Qt Creatorのクイックスタート」の第10章を参照してください。次のセクションから、Qtのグラフィカルビューフレームワークを簡単に紹介します。