天天看點

[Qt教程] 第18篇 2D繪圖(八)雙緩沖繪圖 [Qt教程] 第18篇 2D繪圖(八)雙緩沖繪圖

<a target="_blank" href="http://bbs.qter.org/forum.php?mod=viewthread&amp;tid=120">樓主</a>

[Qt教程] 第18篇 2D繪圖(八)雙緩沖繪圖 [Qt教程] 第18篇 2D繪圖(八)雙緩沖繪圖

 發表于 2013-5-2 22:07:23 | 檢視:

789| 回複: 1

雙緩沖繪圖

版權聲明

導語

在前面一節中,講述了如何實作簡單的塗鴉闆,這一次我們将實作在塗鴉闆上繪制圖形,這裡以矩形為例進行講解。在後面還會提出雙緩沖繪圖的概念。

環境:windows xp + qt 4.8.4+qtcreator 2.6.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兩個點來确定要繪制的矩形的起點、寬和高的。運作程式,用滑鼠拖出一個矩形,效果如下圖所示。

[Qt教程] 第18篇 2D繪圖(八)雙緩沖繪圖 [Qt教程] 第18篇 2D繪圖(八)雙緩沖繪圖

2. 上面已經可以拖出一個矩形了,但是這樣直接在視窗上繪圖,以前畫的矩形是不能儲存下來的。是以我們下面加入畫布,在畫布上進行繪圖。将paintevent()函數更改如下:

    qpainter pp(&amp;pix);

    pp.drawrect(x, y, w, h);

    painter.drawpixmap(0, 0, pix);

       這裡就是将圖形先繪制在了畫布上,然後将畫布繪制到視窗上。我們運作程式,然後使用滑鼠拖出一個矩形,發現出現了很多重影,效果如下圖所示。

[Qt教程] 第18篇 2D繪圖(八)雙緩沖繪圖 [Qt教程] 第18篇 2D繪圖(八)雙緩沖繪圖

       為什麼會出現這種現象呢?大家可以嘗試分别快速拖動滑鼠和慢速拖動滑鼠來繪制矩形,結果會發現,拖動速度越快,重影越少。其實,在我們拖動滑鼠的過程中,螢幕已經重新整理了很多次,也可以了解為paintevent()函數執行了多次,每執行一次就會繪制一個矩形。知道了原因,就有方法來避免這個問題發生了。

1.我們再添加一個輔助畫布,如果正在繪圖,也就是滑鼠按鍵還沒有釋放的時候,就在這個輔助畫布上繪圖,隻有當滑鼠按鍵釋放的時候,才在真正的畫布上繪圖。

       首先在dialog.h檔案中添加兩個私有變量:

qpixmap temppix; //輔助畫布

bool isdrawing; 

 //标志是否正在繪圖

       然後到dialog.cpp的構造函數中對變量進行初始化:

isdrawing = false;

下面再更改paintevent()函數:

    if(isdrawing) //如果正在繪圖,就在輔助畫布上繪制

    {

       //将以前pix中的内容複制到temppix中,保證以前的内容不消失

       temppix = pix;

       qpainter pp(&amp;temppix);

       pp.drawrect(x,y,w,h);

       painter.drawpixmap(0, 0, temppix);

    } else {

       qpainter pp(&amp;pix);

       painter.drawpixmap(0,0,pix);

    }

       下面還需要更改滑鼠按下事件處理函數和滑鼠釋放事件處理函數的内容:

void dialog::mousepressevent(qmouseevent *event)

    if(event-&gt;button()==qt::leftbutton) //滑鼠左鍵按下

       lastpoint = event-&gt;pos();

       isdrawing = true; 

 //正在繪圖

void dialog::mousereleaseevent(qmouseevent *event)

    if(event-&gt;button() == qt::leftbutton) //滑鼠左鍵釋放

       endpoint = event-&gt;pos();

       isdrawing = false; 

  //結束繪圖

       update();

       當滑鼠左鍵按下時我們開始标記正在繪圖,當按鍵釋放時我們取消正在繪圖的标記。現在運作程式,已經可以實作正常的繪圖了。效果如下圖所示。

[Qt教程] 第18篇 2D繪圖(八)雙緩沖繪圖 [Qt教程] 第18篇 2D繪圖(八)雙緩沖繪圖

2.雙緩沖繪圖

       根據這個例子所使用的技巧,我們引出所謂的雙緩沖繪圖的概念。雙緩沖(double-buffers)繪圖,就是在進行繪制時,先将所有内容都繪制到一個繪圖裝置(如qpixmap)上,然後再将整個圖像繪制到部件上顯示出來。使用雙緩沖繪圖可以避免顯示時的閃爍現象。從qt

4.0開始,qwidget部件的所有繪制都自動使用了雙緩沖,是以一般沒有必要在paintevent()函數中使用雙緩沖代碼來避免閃爍。

       雖然在一般的繪圖中無需手動使用雙緩沖繪圖,不過要想實作一些繪圖效果,還是要借助于雙緩沖的概念。比如這個程式裡,我們要實作使用滑鼠在界面上繪制一個任意大小的矩形。這裡需要兩張畫布,它們都是qpixmap執行個體,其中一個temppix用來作為臨時緩沖區,當滑鼠正在拖動矩形進行繪制時,将内容先繪制到temppix上,然後将temppix繪制到界面上;而另一個pix作為緩沖區,用來儲存已經完成的繪制。當松開滑鼠完成矩形的繪制後,則将temppix的内容複制到pix上。為了繪制時不顯示拖影,而且保證以前繪制的内容不消失,那麼在移動滑鼠過程中,每繪制一次,都要在繪制這個矩形的原來的圖像上進行繪制,是以需要在每次繪制temppix之前,先将pix的内容複制到temppix上。因為這裡有兩個qpixmap對象,也可以說有兩個緩沖區,是以稱之為雙緩沖繪圖。

結語

涉及到的源碼: 

[Qt教程] 第18篇 2D繪圖(八)雙緩沖繪圖 [Qt教程] 第18篇 2D繪圖(八)雙緩沖繪圖

kb, 下載下傳次數: 9)