Qt繪圖、事件處理和繪制_第1頁
Qt繪圖、事件處理和繪制_第2頁
Qt繪圖、事件處理和繪制_第3頁
Qt繪圖、事件處理和繪制_第4頁
Qt繪圖、事件處理和繪制_第5頁
已閱讀5頁,還剩62頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、Qt 繪圖、事件處理和繪制課程主要內容Qt繪制事件Qt 2D繪圖畫筆畫刷基本圖形和文本繪制漸變填充繪制文本圖像處理坐標系統(tǒng)與坐標變換繪圖舉例:表盤Qt繪制事件事件處理和繪制(Painting)當應用程序收到繪制事件時,就會調用QWidget:paintEvent(),該函數(shù)就是繪制控件的地方有兩種方法要求重繪一個控件update() 把重繪事件添加到事件隊列中重復調用update() 會被Qt合并為一次不會產(chǎn)生圖像的閃爍可帶參數(shù)指定重繪某個區(qū)域repaint() 立即產(chǎn)生繪制事件一般情況下不推薦使用此方法只使用在需要立即重繪的特效情況下可帶參數(shù)指定重繪某個區(qū)域事件處理和繪制(Painting)

2、為處理繪制事件,只需要重寫paintEvent函數(shù),并在該函數(shù)中實例化一個QPainter對象進行繪制class MyWidget : public QWidget .protected: void paintEvent(QPaintEvent*);void MyWidget:paintEvent(QPaintEvent *ev) QPainter p(this); .基本繪制PipelineQPainter類提供繪制操作QPaintEngine類提供平臺相關的APIQPaintDevice代表繪制2D圖像的畫布如下繼承QPaintDevice的類對象都可用于QPainter繪制QWidget

3、, QImage, QPixmap, QPicture, QPrinter, QSvgGenerator , QGLPixelBuffer, QGLFrameBufferObject, .Qt 2D繪圖QT 2D繪圖Qt4中的2D繪圖部分稱為Arthur繪圖系統(tǒng)。它由3個類支撐整個框架,QPainter,QPaintDevice和QPaintEngineQPainter用來執(zhí)行具體的繪圖相關操作如畫點,畫線,填充,變換,alpha通道等。QPaintDevice是QPainter用來繪圖的繪圖設備,Qt中有幾種預定義的繪圖設備,如QWidget,QPixmap,QImage等。他們都從QPai

4、ntDevice繼承。QPaintEngine提供了QPainter在不同設備上繪制的統(tǒng)一接口,通常對開發(fā)人員是透明的。使用QPainter在QPainterDevice上進行繪制,它們之間使用QPaintEngine進行通訊。從開始,Graphics View框架取代了QCanvas,QGraphics View框架使用了MVC模式,適合對大量2D圖元的管理,Graphics View框架中,場景(scene)存儲了圖形數(shù)據(jù),它通過視圖(view)以多種表現(xiàn)形式,每個圖元(item)可以單獨進行控制。QPainter線和輪廓都可以用畫筆(QPen)進行繪制,用畫刷(QBrush)進行填充。字

5、體使用QFont類定義,當繪制文字時,Qt使用指定字體的屬性,如果沒有匹配的字體,Qt將使用最接近的字體通常情況下,QPainter以默認的坐標系統(tǒng)進行繪制,也可以用QMatrix類對坐標進行變換QPainter當繪制時,可以使用QPainter:RenderHint來告訴繪圖引擎是否啟用反鋸齒功能使圖變得平滑QPainter:RenderHint的可取值QPainter:Antialiasing:告訴繪圖引擎應該在可能的情況下進行邊的反鋸齒繪制QPainter:TextAntialiasing:盡可能的情況下文字的反鋸齒繪制QPainter:SmoothPixmapTransform:使用平

6、滑的pixmap變換算法(雙線性插值算法),而不是近鄰插值算法QPainter的繪圖函數(shù)drawArc() 弧drawChord() 弦drawConvexPolygon() 凸多邊形drawEllipse() 橢圓drawImage() QImage表示的圖像drawLine() 線drawLines() 多條線drawPath() 路徑drawPicture() 按QPainter指令繪制drawPie() 扇形drawPixmap() QPixmap表示的圖像drawPoint() 點drawPoints() 多個點drawPolygon() 多邊形drawPolyline() 多折線d

7、rawRect() 矩形drawRects() 多個矩形drawRoundRect() 圓角矩形drawText() 文字drawTiledPixmap() 平鋪圖像drawLineSegments() 繪制折線畫筆畫筆畫筆的屬性包括線型、線寬、顏色等。畫筆屬性可以在構造函數(shù)中指定,也可以使用setStyle(),setWidth(),setBrush(),setCapStyle(),setJoinStyle()等函數(shù)設定Qt中,使用Qt:PenStyle定義了6種畫筆風格,分別是Qt:SolidLine,Qt:DashLine,Qt:DotLine,Qt:DashDotLine,Qt:Das

8、hDotDotLine,Qt:CustomDashLine。自定義線風格(Qt:CustomDashLine),需要使用QPen的setDashPattern()函數(shù)來設定自定義風格。線型Qt:SolidLineQt:DashLineQt:DotLineQt:DashDotLineQt:DashDotDotLineQt:CustomDashLine 由dashPattern控制畫筆端點風格(cap style)端點風格決定了線的端點樣式,只對線寬大于1的線有效。Qt種定義了三種端點風格用枚舉類型Qt:PenCapStyle表示,分別為Qt:SqureCap,QT:FlatCap,Qt:Roun

9、dCap。連接風格(Join style)連接風格是兩條線如何連接,連接風格對線寬大于等于1的線有效。Qt定義了四種連接方式,用枚舉類型Qt:PenStyle表示。分別是Qt:MiterJoin,Qt:BevelJoin,Qt:RoundJoin,Qt:SvgMiterJoin。端點風格和連接風格連接風格Qt:BevelJoin (default)Qt:MiterJoinQt:RoundJoin端點風格Qt:SquareCap (default):矩形封線尾Qt:FlatCap:不封線尾Qt:RoundCap畫筆示例QPainter p(this);QPen pen(Qt:black, 5);

10、p.setPen(pen);p.drawPolygon(polygon);畫刷畫刷在Qt中圖形使用QBrush進行填充,畫刷包括填充顏色和風格(填充模式)。在Qt中,顏色使用QColor類表示,QColor支持RGB,HSV,CMYK顏色模型。QColor還支持alpha混合的輪廓和填充。RGB是面向硬件的模型。顏色由紅綠藍三種基色混合而成。HSV/HSL模型比較符合人對顏色的感覺,由色調(0-359),飽和度(0-255),亮度(0-255)組成,主要用于顏色選擇器。CMYK由青,洋紅,黃,黑四種基色組成。主要用于打印機等硬件拷貝設備上。每個顏色分量的取值是0-255。另外QColor還可以

11、用中定義的任何顏色名為參數(shù)初始化。基本模式填充包括有各種點、線組合的模式。QColorQColor的構造函數(shù)r(red), g(green), b(blue), a(alpha)的取值范圍為0-255Alpha控制透明度255:不透明0:完全透明Qt預定義顏色QColor( int r, int g, int b, int a )顏色微調顏色可以通過如下函數(shù)進行微調QColor:lighter( int factor )QColor:darker( int factor )darkerlighterQt:redQRgbQRgb類可以用于保存顏色值,可與QColor相互轉換獲取32-bit的RG

12、B顏色值+alpha值創(chuàng)建新顏色獲取單獨某個顏色值:qRed, qGreen, qBlue, qAlpha獲取灰度值QRgb orange = qRgb(255, 127, 0);QRgb overlay = qRgba(255, 0, 0, 100);int red = qRed(orange);int gray = qGray(orange);實色畫刷調用畫刷構造函數(shù)QBrush red(Qt:red);QBrush odd(QColor(55, 128, 97);QPainter p(this);p.setPen(Qt:NoPen);p.setBrush(Qt:red);p.drawPo

13、lygon(polygon);模式畫刷模式化刷構造函數(shù)QBrush( const QColor &color, Qt:BrushStyle style )帶紋理的畫刷以QPixmap為參數(shù)的構造函數(shù)如果使用黑白的pixmap,則用畫刷顏色如果使用彩色pixmap,則用pixmap的顏色QBrush( const QPixmap &pixmap )QPixmap pacPixmap(pacman.png);painter.setPen(QPen(Qt:black, 3);painter.setBrush(pacPixmap);painter.drawEllipse(rect();基本圖形和文本繪

14、制基本圖形繪制實現(xiàn)paintEvent函數(shù)void RectWithCircle:paintEvent(QPaintEvent *ev) QPainter p(this); p.setBrush(Qt:green); p.drawRect(10, 10, width()-20, height()-20); p.setBrush(Qt:yellow); p.drawEllipse(20, 20, width()-40, height()-40);基本文本繪制QPainter:drawTextQPainter p(this);QFont font(Helvetica);p.setFont(font

15、);p.drawText(20, 20, 120, 20, 0, Hello World!);font.setPixelSize(10);p.setFont(font);p.drawText(20, 40, 120, 20, 0, Hello World!);font.setPixelSize(20);p.setFont(font);p.drawText(20, 60, 120, 20, 0, Hello World!);QRect r;p.setPen(Qt:red);p.drawText(20, 80, 120, 20, 0, Hello World!, &r);r返回文本外邊框的矩形區(qū)域

16、漸變填充漸變填充Qt4提供了漸變填充的畫刷,漸變填充包括兩個要素:顏色的變化和路徑的變化。顏色變化可以指定從一種顏色漸變到另外一種顏色。路徑變化指在路徑上指定一些點的顏色進行分段漸變。Qt4中,提供了三種漸變填充線性(QLinearGradient)圓形(QRadialGradient)圓錐漸變(QConicalGradient)所有的類都從QGradient類繼承構造漸變填充的畫刷QBrush b = QBrush( QRadialGradient( . ) );填充設置從圖形的起點到終點,以從0至1的比例漸變填充完成0-1范圍的填充后,后續(xù)顏色鋪開的方式可以不同,通過setSpread()

17、 函數(shù)來設置QGradient:setColorAt( qreal pos, QColor );QGradient:PadSpread(default)QGradient:RepeatSpreadQGradient:ReflectSpread線性漸變填充線性漸變填充指定兩個控制點,畫刷在兩個控制點之間進行顏色插值。通過創(chuàng)建QLinearGradient對象來設置畫刷。 QPainter p(this); QLinearGradient g(0, 0, 100, 100); g.setColorAt(0.0, Qt:white); g.setColorAt(1.0, Qt:blue); p.se

18、tBrush(g); p.drawRect(0, 0, 100, 100);在QGradient構造函數(shù)中指定線性填充的兩點分別為(0,0),(100,100)。setColorAt()函數(shù)在0-1之間設置指定位置的顏色。線型填充示例setColorAt(0.7, QColor(255, 0, 0)setColorAt(1.0, QColor(255, 255, 0)setColorAt(0.0, QColor(0, 0, 0)圓形漸變填充圓形漸變填充需要指定圓心,半徑和焦點,QRadialGradient ( qreal cx, qreal cy, qreal radius, qreal f

19、x, qreal fy )。畫刷在焦點和圓上的所有點之間進行顏色插值。創(chuàng)建QRadialGradient對象設置畫刷 QPainter painter(this); QRadialGradient radialGradient(50, 50, 50, 30, 30); radialGradient.setColorAt(0.0, Qt:white); radialGradient.setColorAt(1.0, Qt:blue); painter.setBrush(radialGradient); painter.drawRect(0, 0, 100, 100);圓錐漸變填充圓錐漸變填充指定圓

20、心和開始角,QConicalGradient ( qreal cx, qreal cy, qreal angle )。畫刷沿圓心逆時針對顏色進行插值,創(chuàng)建QConicalGradient對象并設置畫刷。 QPainter painter(this); QConicalGradient conicalGradient(50, 50, 90); conicalGradient.setColorAt(0, Qt:white); conicalGradient.setColorAt(1, Qt:blue); painter.setBrush(conicalGradient); painter.draw

21、Rect(0, 0, 100, 100);為了實現(xiàn)自定義填充,還可以使用QPixmap或者QImage對象進行紋理填充。兩種圖像分別使用setTexture()和setTextureImage()函數(shù)加載紋理。繪制文本文本繪制使用QPainter進行文本繪制基本文本繪制帶選項的文本繪制帶返回信息的文本繪制drawText( QPoint, QString )drawText( QRect, QString, QTextOptions )drawText( QRect, flags, QString, QRect* )使用字體Qt提供了QFont類來表示字體,當創(chuàng)建QFont對象時,Qt會使用指

22、定的字體,如果沒有對應的字體,Qt將尋找一種最接近的已安裝字體Font familySizeBold / Italic / Underline / Strikeout / 字體信息可以通過QFontInfo取出,并可用QFontMetrics取得字體的相關數(shù)據(jù)。使用QApplication:setFont()可以設置應用程序默認的字體當QPainter繪制指定的字體中不存在的字符時將繪制一個空心的正方形。Font Family在構造函數(shù)中指定字體得到可用字體列表QFont font(Helvetica);font.setFamily(Times);QFontDatabase database;

23、QStringList families = database.families();Font Size字體尺寸可以用像素尺寸(pixel size)或點陣尺寸(point size)QFont font(Helvetica);font.setPointSize(14); / 14 points high / depending on the paint devices dpifont.setPixelSize(10); / 10 pixels high字體效果可以激活字體效果QWidget:font函數(shù)和QPainter:font函數(shù)返回 現(xiàn)有字體的const引用,因而需要先拷貝現(xiàn)有font

24、,再做修改Normal, bold, italic, strike out, underline, overlineQFont tempFont = w-font();tempFont.setBold( true );w-setFont( tempFont );測量文本大小QFontMetrics可用于測量文本和font的大小boundingRect函數(shù)可用于測量文本塊的大小QImage image(200, 200, QImage:Format_ARGB32);QPainter painter(&image);QFontMetrics fm(painter.font(), &image);q

25、Debug(width: %d, fm.width(Hello Qt!);qDebug(height: %d, fm.boundingRect(0, 0, 200, 0, Qt:AlignLeft | Qt:TextWordWrap, loremIpsum).height();中文顯示問題使用QTextCodec類#include QTextCodec *codec = QTextCodec:codecForName(GB2312); / or / QTextCodec *codec = QTextCodec:codecForName(UTF-8);QTextCodec:setCodecFor

26、Locale(codec); int ret = QMessageBox:warning(0, tr(PathFinder), tr(您真的想要退出?), QMessageBox:Yes | QMessageBox:No);圖像處理圖像處理Qt提供了4個處理圖像的類。QImage,QPixmap,QBitmap,QPicure。它們有著各自的特點。QImage優(yōu)化了I/O操作,可以直接存取操作像素數(shù)據(jù)。QPixmap優(yōu)化了在屏幕上顯示圖像的性能。QBitmap從QPixmap繼承,只能表示兩種顏色。QPicture是可以記錄和重啟QPrinter命令的類。轉換在QImage和QPixmap之間

27、轉換QImage QPixmap:toImage();QPixmap QPixmap:fromImage( const QImage& );讀入和保存如下代碼使用QImageReader和QImageWriter類進行,這些類在保存時通過文件的擴展名確定文件格式QPixmap pixmap( image.png );pixmap.save( image.jpeg );QImage image( image.png );image.save( image.jpeg );在QImage上繪制QImage是QPaintDevice的子類,因而QPainter可以在其上繪制QImage image(

28、100, 100, QImage:Format_ARGB32 );QPainter painter(&image);painter.setBrush(Qt:red);painter.fillRect( image.rect(), Qt:white );painter.drawRect( image.rect().adjusted( 20, 20, -20, -20 ) );image.save( image.jpeg );在QPixmap上繪制QPixmap是QPaintDevice的子類,因而QPainter可以在其上繪制主要用于屏幕繪制void MyWidget:imageChanged(

29、 const QImage &image ) pixmap = QPixmap:fromImage( image ); update();void MyWidget:paintEvent( QPaintEvent* ) QPainter painter( this ); painter.drawPixmap( 10, 20, pixmap );坐標系統(tǒng)與坐標變換坐標系統(tǒng)Qt坐標系統(tǒng)由QPainter控制,同時也由QPaintDevice和QPaintEngine類控制。Qt繪圖設備默認坐標原點是左上角,X軸向右增長,Y軸向下增長,默認的單位在基于像素的設備上是像素,在打印機設備上是1/72英寸

30、毫米)QPainter的邏輯坐標與QPainterDevice的物理坐標之間的映射由QPainter的變換矩陣worldMatrix()、視口viewport() 和窗口window()處理。未進行坐標變換的情況下,邏輯坐標和物理坐標是一致的坐標值的表示方法如果不進行坐標變換,直接進行繪圖可用QPainter的window()函數(shù)取得繪圖窗口然后在此繪圖窗口內進行繪制使用QPoint, QSize, 和QRect表示坐標值和區(qū)域QPoint: point(x, y)QSize: size(width, height)QRect: point 和 size (x, y, width, heigh

31、t)QPointF/QSizeF/QRectF用于表示浮點數(shù)坐標坐標變換通常QPainer在設備的坐標系統(tǒng)上繪制圖形,但QPainter也支持坐標變換。QPainter:scale()函數(shù):比例變換QPainter:rotate()函數(shù):旋轉變換QPainter:translate()函數(shù):平移變換QPainter:shear()函數(shù):圖形進行扭曲變換所有變換操作的變換矩陣都可以通過QPainter:wordMatrix()函數(shù)取出。不同的變換矩陣可以使用堆棧保存。用QPainter:save()保存變換矩陣到堆棧,用QPainter:restore()函數(shù)將其彈出堆棧。坐標變換坐標變換的順序

32、很重要在做平移變換、旋轉變換和扭曲變換時,原點也很重要 p.setBrush(Qt:red); p.drawRect(200, 20, 120, 120); p.translate(0, 100); p.drawRect(200, 20, 120, 120); p.rotate(35); p.drawRect(200, 20, 120, 120); p.setBrush(Qt:red); p.drawRect(200, 20, 120, 120); p.rotate(35); p.drawRect(200, 20, 120, 120); p.translate(0, 100); p.drawR

33、ect(200, 20, 120, 120);坐標變換的保存和恢復通過save和restore函數(shù),可以將坐標變換的狀態(tài)保存和恢復 QPoint rotCenter(50, 50); qreal angle = 42; p.save(); p.translate(rotCenter); p.rotate(angle); p.translate(-rotCenter); p.setBrush(Qt:red); p.setPen(Qt:black); p.drawRect(25,25, 50, 50); p.restore(); p.setPen(Qt:NoPen); p.setBrush(QCo

34、lor(80, 80, 80, 150); p.drawRect(25,25, 50, 50);應用變換畫紅色矩形畫灰色矩形可以以任何坐標軸做旋轉操作,以產(chǎn)生3D效果p.setBrush(Qt:gray); p.setRenderHint(QPainter:Antialiasing);p.drawRect(100,100, 100, 100);QTransform t;t.translate(150,0);t.rotate(60, Qt:YAxis);p.setTransform(t, true);p.setBrush(Qt:red);p.drawRect(-50,100, 100, 100)

35、;視口和窗口視口表示物理坐標下的任意矩形。而窗口表示在邏輯坐標下的相同矩形。視口由QPainter的viewport ()函數(shù)獲取窗口由QPainter的window ()函數(shù)獲取默認情況下邏輯坐標與物理坐標是相同的,與繪圖設備上的矩形也是一致的。使用窗口視口變換可以使邏輯坐標符合自定義要求,這個機制通常用來完成設備無關的繪圖代碼。通過調用QPainter:setWindow()函數(shù)可以完成坐標變換設置窗口或視口矩形實際上是執(zhí)行線性變換。本質上是窗口四個角映射到對應的視口四個角,反之亦然。因此,應注意保持視口和窗口x軸和y軸之間的比例變換一致,從而保證變換不會導致繪制變形。繪圖舉例:表盤表盤自

36、定義繪制可以與鍵盤和鼠標交互表盤畫表盤的背景void CircularGauge:paintEvent(QPaintEvent *ev) QPainter p(this); int extent; if (width()height() extent = height()-20; else extent = width()-20; p.translate(width()-extent)/2, (height()-extent)/2); p.setPen(Qt:white); p.setBrush(Qt:black); p.drawEllipse(0, 0, extent, extent); .

37、畫背景圓形將油表放在中心位置表盤畫表盤的刻度void CircularGauge:paintEvent(QPaintEvent *ev) . p.translate(extent/2, extent/2); for(int angle=0; angle=270; angle+=45) p.save(); p.rotate(angle+135); p.drawLine(extent*0.4, 0, extent*0.48, 0); p.restore(); .注意save和restore函數(shù)簡單調用rotate(45)會增大舍入誤差表盤畫表盤的指針void CircularGauge:paintEvent

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論