因為,這個在之後非常重要,所以,在這裡說明一下
void QWidget::repaint () [slots]
把整個畫布以背景重新粉刷過一次,然後,呼叫void QWidget::paintEvent ( QPaintEvent * ),參數的部分就應該是傳整個畫布。
void QWidget::repaint ( const QRect & r, bool erase = TRUE ) [slots]
會在r這一個區域用背景重新粉刷過一次,然後,呼叫void QWidget::paintEvent(QPaintEvent *),參數的部分就是r。
repaint的部分其實就是決定要把目前的畫面哪一個部分要把它由背景填滿,也就是說,它的工作就是清除。
真正畫圖的部分是由QPaint去實作的,而我們通常把QPaint的宣告放在paintEvent中,因為,當我們呼叫repaint(const QRect &r,bool erase = TRUE)時,程式會透過它呼誓paintEvent(),並把r當參數傳給paintEvent(),這個時候,我們就可以在paintEvent中寫出畫圖的程式。
以下是畫圖的例子:
QPainter p( pd ); // 決定要在哪一個設備上畫圖
p.setBrush( blue ); // 設定畫筆為藍色
p.setPen( NoPen ); // 設定沒有邊框
p.drawEllipse(0,0,10,10); // 畫一個10*10的橢圓,剛好就是一個直徑為10的圓啦~
下面再一個例子:
void CannonField::paintEvent( QPaintEvent * )
{
QString s = "Angle = " + QString::number( ang );
QPainter p( this );
p.drawText( 200, 200, s );
}
void CannonField::paintEvent( QPaintEvent * )
{
QString s = "Angle = " + QString::number( ang );
QPainter p;
p.begin( this );
p.drawText( 200, 200, s );
p.end();
}
上面兩個程式碼的義意是一樣的。
begin():開始繪製
end():結束繪製。繪製時使用的任何資源都被釋放。注意雖然你幾乎不需要調用end(),建構函數將會執行它,但是至少還有一種情況需要它,就是雙重緩衝(就是先把要畫的先畫在pixmap再畫到qpainter)。
QPainter p( myPixmap, this )
// ...
p.end(); // 停止在myPixmap上的繪製
p.begin( this );
p.drawPixmap( myPixmap );
這是我們第一次試圖寫一個繪畫事件處理程序。
這個事件參數包含一個繪畫事件的描述。
QPaintEvent包含一個必須被刷新的視窗元件的區域。
現在,我們比較懶惰,並且只是畫每一件事。
我們的程式碼在一個固定位置顯示窗口部件的角度值。
首先我們創建一個含有一些文本和角度值的QString,
然後我們創建一個操作這個窗口部件的QPainter並使用它來畫這個字符串。
我們一會兒會回到QPainter,它可以做很多事。
repaint
void QWidget::repaint ( int x, int y, int w, int h, bool erase = TRUE ) [slots]
通過立即調用paintEvent()來直接重新繪製視窗元件,
除非更新是失效的或者窗口部件被隱藏。
如果erase為真,Qt在paintEvent()調用之前擦除區域(x,y,w,h)。
如果w是負數,它被width()-x替換,並且如果h是負數,它被height()-y替換。
如果你需要立即重新繪製,我們建議使用repaint(),比如在動畫期間。在絕大多數情況下,update()更好,因為它允許Qt來優化速度並且防止閃爍。
警告:如果你在一個函數中調用repaint(),而它自己又被paintEvent()調用,你也許會看到無線循環。update()函數從來不會產生循環。
在一開始的時候,就會執行一次paintEvent
沒有留言:
張貼留言