org.eclipse.swt.graphics包(package),包含了管理圖形資源的類。只要實現了org.eclipse.swt.graphics.Drawable接口,就可在上面繪畫,包括 org.eclipse.swt.widgets.Control 和 org.eclipse.swt.graphics.Image 。 org.eclipse.swt.graphics.GC封裝了所有繪畫API,包括如何繪製線條、圖形、如何繪製文本、圖像以及填充圖形。 本篇將展現如何使用GC在圖像上繪畫, 控件的繪畫事件(paintEvent)回調。畫布(Canvas)控件,由於不一樣的繪畫操做,擁有不少構造風格常量容許你指定什麼時候以及如何產生繪畫,本篇也將展現這些東西。
英文原文:Graphics Context - Quick on the draw http://www.eclipse.org/articles/Article-SWT-graphics/SWT_graphics.htmlhtml
目錄:shell
SWT圖形系統使用了與控件(Control)相同的座標習慣,即客戶區最左上角開始的點爲原點(0,0),x軸座標向右增長,y軸座標向下增長。Point 類被用於描述位置(座標系統中的位置)以及偏移量(SWT中並無Dimension類,矩形(rectangle)的大小是由Point類捕獲的x、y座標點偏移量到原點座標來描述的)。編程
圖形可以被畫在任何實現了org.eclipse.swt.graphics.Drawable接口的東西上,好比控件(Control)、圖像(Image)、顯示設備或者打印設備。 org.eclipse.swt.graphics.GC 就是封裝了執行繪畫操做的圖形上下文(graphics context)。通常有兩種使用GC的方法:一種是讓Drawable 實例做爲GC構造函數的參數獲取的GC,另一種是繪畫事件(paintEvent)回調提供的GC。canvas
如下代碼是把一個圖像做爲構造參數獲取圖像的GC,而後在它上面繪製線條。 從左上角頂點(0,0)處向右下角頂點畫線條 從右上角頂點向左下角頂點畫線條。eclipse
Image image = new Image(display,"C:/devEclipse_02/eclipse/plugins/org.eclipse.platform_2.0.2/eclipse_lg.gif");
GC gc = new GC(image);
Rectangle bounds = image.getBounds();
gc.drawLine(0,0,bounds.width,bounds.height);
gc.drawLine(0,bounds.height,bounds.width,0);
gc.dispose();
image.dispose();
jsp
原始圖像 | 繪製線條後的圖像 |
由你建立的GC,就得由你負責銷燬它。調用 dispose()方法。關於怎樣管理 SWT 資源的更多信息請參見 SWT: The Standard Widget Toolkit 。一個 GC 實例應該在使用完後就儘量快的釋放,這是由於每個GC 都須要佔用底層系統平臺資源,而在某些操做系統平臺中,這些資源是至關匱乏的,例如Windows 98僅僅提供了5個GC 對象。ide
org.eclipse.swt.widgets.Control 實現了Drawable接口,因此你能夠在控件(Control)上繪畫,圖像(Image)上繪畫方法與控件相同(把控件或圖像做爲參數傳給GC獲取控件或圖像的GC,而後在其上進行繪畫)。可是,圖像(Image)上的繪畫與控件有所不一樣是圖像的修改是永恆不變的。若是使用GC在控件上進行繪畫,操做系統自身在繪製控件時會覆蓋你所作的繪畫操做。正確的方法的是爲控件添加一個繪畫監聽器,這個監聽器類就是org.eclipse.swt.events.PaintListener,而後在監聽器中回調方法參數就是org.eclipse.swt.events.PaintEvent的一個實例。PaintEvent 包含了一GC,這樣在控件上面或者是指定區域裏面進行繪畫的環境就準備好了
函數
如下代碼 給Shell添加了一個繪畫監聽, 而後在paintControl()方法中畫一條鏈接原點到底部右下角的直線。工具
Shell shell = new Shell(display);
shell.addPaintListener(new PaintListener(){
public void paintControl(PaintEvent e){
Rectangle clientArea = shell.getClientArea();
e.gc.drawLine(0,0,clientArea.width,clientArea.height);
}
});
shell.setSize(150,150)
字體
雖然Shell的大小設置爲(150,150), 但實際上可繪畫的區域比這還要再小一些,由於Shell還包括了邊框、工具欄以及菜單欄,這也就是咱們所要了解的客戶區域。任何面板(Composite)都是使用getClientArea()方法獲取客戶區域的。
由於應用程序老是在底層OS繪製完控件後才獲得繪畫事件,因此繪畫事件中的GC進行繪畫後的效果就能夠最終顯示在控件上面了。固然也有例外,好比工具欄區域就不能在上面進行繪畫。org.eclipse.swt.widgets.Canvas
可以用來進行多方面的圖形繪畫操做。
剪切(Clipping)
一個GC的剪切區域就是發生繪畫的那部分,這裏有個例子,若是你要填充出一個有缺口的三角形形狀,一種方法是畫出多個三角形和矩形組合出這麼一個形狀;固然也有另外一種方法,就是利用GC的剪切操做。
shell.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
Rectangle clientArea = shell.getClientArea();
int width = clientArea.width;
int height = clientArea.height;
e.gc.setClipping(20,20,width - 40, height - 40);
e.gc.setBackground(display.getSystemColor(SWT.COLOR_CYAN));
e.gc.fillPolygon(new int[] {0,0,width,0,width/2,height});
}
});
這段代碼在Shell上畫了一個三角形。 左上角和右上角鏈接到底部邊緣的中間。使用一個矩形CG對其進行剪切。 最後顯示出被剪切的矩形區域。
當控件發生繪畫事件,GC老是剪切須要重繪的那部分區域。例如,另外一個窗口移到了一個SWT shell的前面,隨後又移走。那麼須要從新顯示的就是GUI被損壞的那部分(shell被覆蓋的那部分),一個繪畫事件就是事件隊列。當繪畫事件發生,paintControl(PaintEvent evt)
方法中的參數就包含了控件中須要的重繪區域的x、y座標字段及寬和高字段。控件的受損部分可以包含若干個相分離的矩形區域,當繪畫事件發生,控件的受損部分不止一個時,那麼它們就會被合併成一個單一的矩形。這一步是由底層平臺來實現的,由於多個繪畫事件在單獨的一個回調過程當中處理有利於執行。
在上面的例子中每當 paintControl(PaintEvent)被調用的時候, 就將在PaintEvent's area中尋找一個優化。繪畫事件(paint event)極可能不交叉在繪畫的形狀(shape)中,在這種狀況下,就不須要繪畫(painting)或者指使須要一部分重畫而已。依靠繪畫的類型,就能夠解決GC所選擇的繪畫部分,但事實上這要比GC剪切花費更多開銷,並且在實踐中經常忽視這些被損壞的區域讓GC從新繪畫所有,只有在刷新操做中才會依賴剪切。
若是程序須要手工損壞控件的某部分區域,可使用Control.redraw(int x, int y, int width, int height)或者使用
Control.redraw()
損壞整個客戶區域。此區域就被打上了標記而後包含在下一個繪畫事件中,產生閃屏後,就會當即使用Control.update()方法強制處理控件的繪畫請求。
若是無繪畫請求(也就是客戶區域無損壞), update()就什麼不作。
(譯者注:此處的Control並不單指Control類,而是指全部繼承了Control類的控件類,好比button,canvas,shell等等)
雖然任何控件均可以經過繪畫事件(paintEvent)在其上進行繪製, 可是org.eclipse.swt.widgets.Canvas
是針對圖形操做而特別設計的。能夠直接使用Canvas,也能夠經過添加繪畫事件(paintEvent)使用,還能夠建立Canvas的子類來自定義控件重複使用之。畫布(Canvas)擁有大量的風格樣式來影響繪畫的產生。
Canvas的默認行爲是使用當前背景色填充自身的整個客戶區域。這樣會引發屏閃,由於繪畫事件也是在GC上繪畫,因此用戶就會看到被填充的原始背景色和產生繪畫之間的閃爍。有一種方法可避免此類狀況,在建立Canvas時使用SWT.NO_BACKGROUND樣式。這樣就防止了繪畫背景,意思就是程序要負責繪畫客戶區域的每個像素。
當部件調整大小時,客戶區域會重複繪畫,這就會出現屏幕閃爍。使用SWT.NO_REDRAW_RESIZE 可減小這樣的狀況,控件會減小沒必要要的重繪。好比改變尺寸大小,繪畫事件GC只會剪切須要重繪的部分即底部區域和右邊區域,就像一個反方向的「L」。
在固定大小的GC上繪畫NO-REDRAW_RESIZE樣式能很好的減小屏閃。可是錯誤的使用NO_REDRAW_RESIZE 能夠致使圖造成扁圓形。扁圓形是個大概的說法,事實上是指部件沒有隨大小的調整而進行正確的更新。下面的例子就演示了這樣的狀況。 填充橢圓形。由於在窗口大小改變時沒有產生繪畫事件,由於GC只剪切受損的(發生改變的)區域,而上一個繪畫又沒有被抹去,這就產生了扁圓形狀。( 即便用NO_REDRAW_RESIZE 繪畫事件只處理擴大的那部分區域,原先部分它就無論了).
shell.setLayout(new FillLayout());
final Canvas canvas = new Canvas(shell,SWT.NO_REDRAW_RESIZE);
canvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
Rectangle clientArea = canvas.getClientArea();
e.gc.setBackground(display.getSystemColor(SWT.COLOR_CYAN));
e.gc.fillOval(0,0,clientArea.width,clientArea.height);
}
});
canvas的大小被增大,GC只剪切須要重繪的地方,扁圓形狀就產生了。
問題出在 ,應該使用SWT.NONE 樣式,這樣GC就不會只剪切擴大的部分了。因此當Shell大小增大時整個橢圓形都會被重繪。
final Canvas canvas = new Canvas(shell,SWT.NONE);
任何SWT部件,若是超過一個矩形區域被「損壞」,平臺會把它們合併成一個,也就是說SWT程序只能處理一個繪畫事件。在Canvas上使用NO_MERGE_PAINTS 樣式能夠覆蓋這樣的行爲,能夠爲每個被「損壞」的矩形區域調用繪畫事件監聽。
風格常量NO_BACKGROUND, NO_REDRAW_RESIZE 以及NO_MERGE_PAINTS 可以被使用在任何面板(Composite)以及子類中, 包括Canvas、Shell以及Group。 雖然這是被SWT容許的(不會由異常拋出),但在Composite 類的Javadoc中關於風格有這樣的警告 "... 若是在其餘的Composite子類中(除了Canvas)使用其行爲是不明確的。
"。因此實現圖形繪畫操做Canvas應該是首選。
另外一種減小屏幕閃爍的方法,就是使用雙緩衝技術。你能夠先根據Canvas客戶區域大小建立Image對象,而後使用GC(Image)將其繪畫到Canvas上
; 在繪畫事件GC中調用drawImage(Image image, int x, int y)。
在一些平臺上已經爲你實現了雙緩衝,因此你能夠根據狀況考慮使用三緩衝。
繪製線條和形狀(Drawing lines and shapes)
GC 擁有不少繪畫線條的方法,好比畫鏈接兩個座標點的直線、鏈接多個座標點的直線或者是預先定義好的形狀,線條顏色就是GC的前景色,能夠經過風格樣式常量來決定線條的粗細胖瘦。繪畫事件其GC也有不少相同的屬性(前景色、背景色、以及顏色),而且線條的默認寬度是1像素。
GC.drawLine(int x1, int y1, int x2, int y2);
畫一條從座標點(x1,y1)到座標點(x2,y2)的直線,若是兩點的座標值相同就至關於畫一個圓點。
GC.drawPolyline(int[] pointArray);
畫一條鏈接多個座標點的直線,int[] 存放着要鏈接的x、y座標值。代碼以下:
gc.drawPolyline(new int[] { 25,5,45,45,5,45 });
先是從座標點25,5到45,45,而後從45,45到5,45。
GC.drawPolygon(int[] pointArray);
drawPolyline(int[])的使用與
gc.drawPolyline很類似,不一樣的是最後一個點(5,45)鏈接了第一個點(25,5)。
gc.drawPolygon(new int[] { 25,5,45,45,5,45 });
至關於用三條線段連接三角形的單個端點,從而造成了一個三角形區域。
GC.drawRectangle(int x, int y, int width, int height);
畫一個矩形區域,int x,int y是矩形左上角的座標點,int width,int heighy分別是矩形的寬和高。
gc.drawRectangle(5,5,90,45);
左上角座標點爲(5,5),對角座標點爲(95,50)。
你能夠將Rectangle做爲一個單獨的參數傳送給繪畫方法。GC.drawRectangle(Rectangle);
GC.drawRoundedRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight);
圓角矩形不一樣於標準矩形,它的四角呈圓形。每個圓角實際上就是一個1/4的橢圓形,其弧寬和弧高就是完整橢圓形的寬和高。
gc.drawRoundedRectangle(5,5,90,45,25,15)
畫了一個圓角矩形,左頂角座標值(5,5)。下面是圓角矩形的右下角放大圖,其寬和高分別是2五、15。
雖然調用4次drawArc()和4次drawLine()徹底能夠
實現一個圓角矩形。但在一些平臺下,例如Windows或者Photon,SWT就可使用很是優秀的平臺API。
GC.drawOval(int x, int y, int width, int height);
一個橢圓形是畫在矩形裏的,因此由矩形的左頂點座標以及寬和高來定義。定義一個正圓形一樣使用這個方法。
gc.drawOval(5,5,90,45);
GC.drawArc(int x, int y, int width, int height, int startAngle, int endAngle);
一個弧形是被畫在一個指明瞭高和寬以及左頂角x,y座標的矩形區域內。int startAngle是個角度,是開始畫弧形的位置,開始點就是此角度與X軸座標線相交的那個點。int endAngle一樣是角度,它是弧形結束的位置,道理和int startAngle相同。
gc.drawArc(5,5,90,45,90,200);
這裏畫了一個弧形,從90度垂線和X軸座標相交處開始,而後持續畫200度。
GC.setLineStyle(int style);
線條(Lines)擁有多種風格,org.eclipse.swt.SWT中提供了定義線條風格的常量,這些線條風格常量以
LINE_開頭。
SWT.LINE_SOLID | |
SWT.LINE_DOT | |
SWT.LINE_DASH | |
SWT.LINE_DASHDOT | |
SWT.LINE_DASHDOTDOT |
GC.setLineWidth(int width);
線條的默認寬度是1像素(pixel), 固然也可使用GC的lineWidth字段設置線條寬。
gc.setLineWidth(2); | |
gc.setLineWidth(4); |
由於線條風格影響着全部的繪畫操做,因此這也就使你能夠畫出不一樣邊線風格的矩形或橢圓等圖形。
gc.setLineWidth(3);
gc.drawOval(5,5,40,40);
gc.setLineWidth(1);
gc.setLineStyle(SWT.LINE_DOT);
gc.setForeground(display.getSystemColor(SWT.COLOR_BLUE));
gc.drawRectangle(60,5,60,40);
當GC的屬性被改變,好比像線條的寬度、線條的風格或者是顏色,這些變化都會影響到後續的繪畫操做。以上代碼片斷中,首先設置線條的寬度爲3畫了一個橢圓,隨後從新設置線條屬性畫了一個邊線是虛線的矩形。在SWT圖形編程中,忘記從新設置這些字段屬性的值是常常會犯的錯誤。
繪製文本(Drawing text)
GC之上一樣能夠繪製文本,文字的輪廓可經過GC的foreground color和font肯定。你須要定義它的左上角座標(就是字體的位置)以及字體的高和寬。繪製文本有兩種設置方法:第一種是在drawText()繪製方法裏直接輸入文本它將處理行分隔符和tabs製表符,經常使用來模仿一個Label。第二種是在drawString()繪製方法中輸入字符串,沒有tab以及回車處理,經常使用於更加複雜的控件,就像StyledText經常使用於
Eclipse Java editor那樣。
GC.drawText(String text, int x, int y);
Font font = new Font(display,"Arial",14,SWT.BOLD | SWT.ITALIC);
// ...
gc.drawText("Hello World",5,5);
gc.setForeground(display.getSystemColor(SWT.COLOR_BLUE));
gc.setFont(font);
gc.drawText("Hello\tThere\nWide\tWorld",5,25);
// ...
font.dispose();
drawText API 支持控制轉義字符,\t 就是tab,\n就是回車換行。
GC.drawString(String text, int x, int y);
Font font = new Font(display,"Arial",14,SWT.BOLD | SWT.ITALIC);
// ...
gc.drawString("Hello World",5,5);
gc.setForeground(display.getSystemColor(SWT.COLOR_BLUE));
gc.setFont(font);
gc.drawString("Hello\tThere\nWide\tWorld",5,25);
// ...
font.dispose()
使用drawString時,tab 和回車換行轉義字符沒有被處理。在GC繪製時字符串所佔的大小基於它的內容和GC所設置的字體。獲取字符串所佔寬度能夠分別使用GC.stringExtent(String text)和
GC.textExtent(String text)這兩個方法。 它們所返回的Point的x,y座標值分別就是寬和高。
GC.drawText(String text, int x, int y, boolean isTransparent);
drawText(String text, int x, int y)繪製的文本使用的是GC的當前foreground color。當你但願文本透過背景色在最頂層顯示的畫,你可設置它的isTransparent這個布爾型的參數爲true。此方法在圖像(image)上繪製時特別有用。
Font font = new Font(display,"Arial",12,SWT.BOLD | SWT.ITALIC);
Image image = new Image(display,"C:/devEclipse_02/eclipse/plugins/org.eclipse.platform_2.0.2/eclipse_lg.gif");
GC gc = new GC(image);
gc.drawText("Hello World",5,5);
gc.setFont(font);
gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
gc.drawText("Hello World",5,25,true);
gc.dispose();
image.dispose();
font.dispose();
GC.drawText(String text, int x, int y, int flags);
int flags指的是SWT.DRAW_DELIMITER, SWT.DRAW_TAB, SWT.DRAW_TRANSPARENT 以及 SWT.DRAW_MNEMONIC 樣式常量。這些常量用來肯定是否處理 \n , \t , 是否使用背景色透明,是否處理 &。
gc.drawImage(image,0,0);
gc.drawText("Hello\t&There\nWide\tWorld",5,5,SWT.DRAW_TRANSPARENT);
gc.drawText("Hello\t&There\nWide\tWorld",5,25,SWT.DRAW_DELIMITER | SWT.DRAW_TAB | SWT.DRAW_MNEMONIC );
使用GC的foreground color畫線條(邊線), 使用GC的background color填充形狀。
GC.fillPolygon(int[]);
gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
gc.fillPolygon(new int[] { 25,5,45,45,5,45 })
GC.fillRectangle(int x, int y, int width, int height);
gc.fillRectangle(5,5,90,45);
填充矩形的時候,底部邊線和右邊線是不包含在內的。雖然點(5,5)被包含在填充矩形的代碼中,但右下角點 95,50 (5+90 , 45+5) 不在填充區域的範圍裏,右下角的填充點是94,49。這不一樣於drawRectangle(5,5,90,45),drawRectangle指的是整個形狀,因此其右下角點是
95,50。
舉例說明一下,下面的代碼填充了一個矩形,可是填充的顏色並無覆蓋邊線。填充區域的右上角點座標以及寬和高都減少了1像素。
gc.drawRectangle(5,5,90,45);
gc.setBackground(display.getSystemColor(SWT.COLOR_CYAN));
gc.fillRectangle(6,6,89,44);
GC.fillRoundedRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight);
gc.fillRoundRectangle(5,5,90,45,25,15);
有點像 GC.fillRectangle(...)方法。底部邊框和右邊框都被排除在填充範圍以內,因此底部右下角座標變成了(94,49)而不是(95,50)
GC.fillOval(int x, int y, int width, int height);
gc.fillOval(5,5,90,45);
與其餘的填充APIs類似
GC.fillArc(int x, int y, int widt4h., int height, int startAngle, int endAngle);
gc.fillArc(5,5,90,45,90,200);
fillArc(...)
方法中的參數和drawArc(...)中的參數很類似。fillArc(...)遵照着和其餘填充方法同樣的模式,底部邊框和右邊框不在填充範圍以內。
GC.fillGradientRectangle(int x, int y, int width. int height, vertical boolean);
對矩形進行由前景色到背景色的漸變填充。Vertical爲true表示垂直漸變,反之則表示水平漸變。
gc.setBackgrouind(display,getSystemColor(SWT.COLOR_BLUE));
gc.fillGradientRectangle(5,5,90,45,false);
水平漸變從左邊的黑色前景色開始向右邊藍色背景色變化。正如其餘的填充方法,底部和右邊框是被排除在外的,因此底部右下角會由1像素插入。
gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
gc.setForeground(display.getSystemColor(SWT.COLOR_CYAN));
gc.fillGradientRectangle(5,5,90,45,true);
垂直漸變從上而下,由前景色向背景色變化。
當GC的繪畫發生時你能夠在繪畫表面上編輯圖形的像素值,設置GC的異或(XOR)模式爲true,每種顏色都是三原色紅、綠、藍通過異或(XOR)操做後的結果,那麼你就能夠將幾種顏色通過異或(XOR)操做後獲得新的顏色。
shell.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
// ...
gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
gc.fillRectangle(5,5,90,45);
gc.setXORMode(true);
gc.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
gc.fillRectangle(20,20,50,50);
gc.setBackground(display.getSystemColor(SWT.COLOR_RED));
gc.fillOval(80,20,50,50);
被填充的背景色是白色的(255,255,255)矩形,當在上面覆蓋一層藍色(0,0,255),或(XOR)後的顏色就是黃色(25,255,0)。白背景的部分和黃色異或後就成了黑色(0,0,0)。一個紅色背景的圓,它覆蓋在藍色上面異或(XOR)後就成了紫色(255,0,255)。蓋在白色上面異或(XOR)後就成了青色(0,255,255)。
(譯者注: SWT API幫助文檔中對setXORMode()方法是這樣描述的「此方法在某些平臺下是不被支持的,顯著表現的有Mac OS X,若是你但願你的代碼可運行在全部平臺,應該儘可能避免使用此方法。」)
org.eclipse.swt.graphics.Image
表示一個已經準備好在顯示設備或打印設備上顯示的圖像。建立一個image對象最簡單的方式就是從通過驗證的文件格式中加載文件。支持的文件格式有 GIF, BMP (Windows 位圖), JPG, PNG, 新的Eclipse releases版還支持TIFF格式。
Image image = new Image(display,"C:/eclipse/eclipse/plugins/org.eclipse.platform_2.0.2/eclipse_lg.gif");
GC.drawImage(Image image, int x, int y);
每個圖像(image)都有一個由它自身範圍所決定的大小。例如圖像eclipse_lg.gif的大小就是
115,164 ,可使用image.getBounds()獲取。當繪畫了一個圖像,此圖像就會以它自身範圍的寬度和高度顯示出來。
gc.drawImage(image,5,5);
GC.drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int dstWidth, int dstHeight);
根據原始圖像的寬度和高度,不但能夠繪畫出不一樣大小的圖像還能夠只繪畫原始圖像的局部。
src 參數聯繫圖像自己,要畫完整的圖像,srcX、srcY 使用0,0,寬高就使用圖像的寬高。dst 參數表示圖像被畫在哪裏以及畫成多大。原始圖像的大小是115,164,若要把圖像寬度增長2倍,高度減低一半,可使用下面的語句:
gc.drawImage(image,0,0,115,164,5,5,230,82);
使用src座標可使你只畫出圖像的局部。例如,若是你只想畫出圖像的右上角部分,你能夠設定src座標爲20,0,寬度和高度爲95,82。下面的代碼中dst 寬度和高度一樣使用95,82。經過指定不一樣大小就能夠對圖像進行拉長或收縮操做。
gc.drawImage(image,20,0,95,82,5,5,95,82);
還能完成一些其餘的圖像效果,好比圖像透明度、animation以及alpha通道。但這些不屬於本篇的討論範圍,我但願在之後的文章中可以涉及到這些東西。
本文已經展現瞭如何使用GC畫線條、文本和填充形狀。給構造器傳入一個drawable參數就可以建立其GC,例如一個圖像、或者給控件(control)使用繪畫事件(paintEvent)回調。 GC 的API容許設置前景色繪畫出線條並使用背景色填充。Canvas 控件容許經過繪畫事件(paintEvent)繪畫,而且當繪畫事件發生時它有不少的構造常量可使用。GC 的剪切操做容許你控制只想顯示的部分,還有如何繪畫出不一樣風格的線條以及顯示文本和圖像。