Qt学习笔记之2D绘图
一、概要
Qt中提供了強大的2D繪圖系統,可以使用相同的API在屏幕和繪圖設備上進行繪制,它主要基于QPainter、QPaintDevice和QPaintEngine這三個類。其中QPainter用來執行繪圖操作;QPaintDevice提供繪圖設備,它是一個二維空間的抽象,可以使用QPainter在其上進行繪制;QPaintEngine提供了一些接口,可以用于QPainter在不同的設備上進行繪制。
QPaintEngine類由QPainter和QPaintDevice內部使用,應用程序一般無需和QPaintEngine打交道,除非要創建自己的設備類型。
在繪圖系統中由QPainter來完成具體的繪制操作,QPainter類提供了大量高度優化的函數來完成GUI編程所需要的大部分繪制工作。QPainter可以繪制一切想要的圖形,從最簡單的一條直線到其他任何復雜的圖形,它還可以用來繪制文本和圖片。QPainter可以在繼承自QPaintDevice類的任何對象上進行繪制操作。
QPainter一般在一個部件的重繪事件(Paint Event)的處理函數paintEvent()中進行繪制,首先要創建QPainter對象,然后進行圖形的繪制,最后銷毀QPainter對象。
注:從QWidget類繼承的類都有paintEvent()事件,要在設備上繪圖,只需要重寫此事件函數,并在函數內編寫相應的繪圖代碼就可以了,一般的繪圖設備包括QWidget、QPixmap、QImage等,這些繪圖設備為QPainter提供了一個“畫布”,QPainter可以在這些設備上進行繪圖。
二、窗口各類位置相關函數的區別
其中:
- x()、y()和pos()函數都是獲得整個窗體左上角的坐標位置。
- frameGeometry()與geometry()相對應。frameGeometry()是獲得整個窗體的左上頂點和長、寬值,而geometry()函數獲得的是窗體內中央區域的左上頂點坐標以及長、寬值。
- 直接調用width()和height()函數獲得的是中央區域的長、寬值。
- rect()、size()函數獲得的結果也都是對于窗體的中央區域而言的。size()獲得的是窗體中央區域的長、寬值,rect()與geometry()一樣返回一個QRect對象,這兩個函數獲得的長、寬值是一樣的,都是窗體中央區域的長、寬值,只是左上頂點的坐標值不一樣,geometry()獲得的左上頂點坐標是相對于父窗體而言的坐標,而rect()獲得的左上頂點坐標始終為(0,0)。在實際應用中需根據情況使用正確的位置信息函數以獲得準確的位置尺寸信息,尤其是在編寫對位置精度要求較高的程度時(如地圖瀏覽程序),更應注意函數的選擇,避免產生不必要的誤差。
三、繪圖操作的一般步驟
方式1:
QPainter painter(this)//! 配置相關屬性 setPen(); //設置畫筆, setFont(); //設置字體格式 setBrush(); //設置畫刷setRenderHint(QPainter::Antialiasing); //設置反鋸齒 //設置組合模式,即后面繪制的圖與前面繪制的圖疊加模式,參數是一個QPainter::CompositionMode枚舉類型(類型很多,有40多種,詳情見QT幫助文檔) void QPainter::setCompositionMode(CompositionMode mode)繪圖操作方式2
QPainter painter; painter.begin(this);//! 配置相關屬性 setPen(); //設置畫筆, setFont(); //設置字體格式 setBrush(); //設置畫刷setRenderHint(QPainter::Antialiasing); //設置反鋸齒 //設置組合模式,即后面繪制的圖與前面繪制的圖疊加模式,參數是一個QPainter::CompositionMode枚舉類型(類型很多,有40多種,詳情見QT幫助文檔) void QPainter::setCompositionMode(CompositionMode mode)繪圖操作painter.end();四、一般繪圖演示
void Widget::paintEvent(QPaintEvent *event) {QPainter painter(this);//! 添加畫筆QPen pen;pen.setColor( QColor(255,0,0) );pen.setStyle(Qt::DotLine);pen.setWidth(2);painter.setPen(pen);//! 添加畫刷QBrush brush;brush.setColor(QColor(0,255,0,125));brush.setStyle(Qt::SolidPattern);painter.setBrush(brush);//! 畫矩形框painter.drawRect(10,20,200,100);//! 畫直線painter.drawLine(QPoint(0,0),QPoint(100,100));}輸出結果:?
五、顯示文字演示
?
void Widget::paintEvent(QPaintEvent *event) {QPainter painter(this);//! 添加畫筆QPen pen;pen.setColor( QColor(255,0,0) );pen.setStyle(Qt::DotLine);pen.setWidth(2);painter.setPen(pen);//! 添加畫刷QBrush brush;brush.setColor(QColor(0,255,0,125));brush.setStyle(Qt::SolidPattern);painter.setBrush(brush);//! 畫矩形框painter.drawRect(10,20,200,100);//! 畫直線painter.drawLine(QPoint(0,0),QPoint(100,100));//! 設置字體QFont font;font.setFamily("宋體");font.setPixelSize(10);font.setBold(true);font.setUnderline(true);font.setLetterSpacing(QFont::AbsoluteSpacing,1);painter.setFont(font);//! 繪制文字painter.drawText(QPoint(100,100),"你好");painter.drawText(QRect(10,20,200,100),Qt::AlignCenter,"你好");}六、顯示圖片演示
Qt提供了四個類來處理圖像數據:QImage、QPixmap、QBitmap和QPicture,它們也都是常用的繪圖設備。其中QImage主要用來進行I/O處理,它對I/O處理操作進行了優化,而且也可以用來直接訪問和操作像素;QPixmap主要用來在屏幕上顯示圖像,它對在屏幕上顯示圖像進行了優化;QBitmap是QPixmap的子類,它是一個便捷類,用來處理顏色深度為1的圖像,即只能顯示黑白兩種顏色;QPicture用來記錄并重演QPainter命令。
void Widget::paintEvent(QPaintEvent *event) {QPainter painter(this);QPixmap pix;pix.load("E:/work/qe/myGui3/1.png");painter.drawPixmap(QRect(0,0,pix.width(),pix.height()),pix); }七、繪制路徑演示
如果要繪制一個復雜的圖形,尤其是要重復繪制這樣的圖形,那么可以使用QPainterPath類,然后使用QPainter::drawPath()來進行繪制。QPainterPath類為繪制操作提供了一個容器,可以用來創建圖形并且重復使用。一個繪圖路徑就是由多個矩形、橢圓、線條或者曲線等組成的對象,一個路徑可以是封閉的,例如矩形和橢圓;也可以是非封閉的,例如線條和曲線。
void MainWidget::paintEvent(QPaintEvent *event) {//! 設置字體QFont font;font.setFamily("宋體");font.setPixelSize(64);font.setBold(true);font.setUnderline(true);QPainterPath painterPath;painterPath.addRect(QRect(20,20,200,200));painterPath.moveTo(200,200);painterPath.lineTo(300,400);painterPath.addText(QPoint(300,400),font,"你好");QPainter painter;painter.begin(this);//! 設置畫筆QPen pen;pen.setWidth(1);pen.setStyle(Qt::DotLine);pen.setColor(QColor(255,0,0));painter.setPen(pen);//! 設置畫刷QBrush brush;brush.setColor(QColor(0,255,0,125));brush.setStyle(Qt::SolidPattern);painter.setBrush(brush);painter.drawPath(painterPath);painter.end();}?
八、雙緩沖繪圖演示
雙緩沖(double-buffers)繪圖,就是在進行繪制時,先將所有內容都繪制到一個繪圖設備(如QPixmap)上,然后再將整個圖像繪制到部件上顯示出來。使用雙緩沖繪圖可以避免顯示時的閃爍現象。從Qt 4.0開始,QWidget部件的所有繪制都自動使用了雙緩沖,所以一般沒有必要在paintEvent()函數中使用雙緩沖代碼來避免閃爍。
雖然在一般的繪圖中無需手動使用雙緩沖繪圖,不過要想實現一些繪圖效果,還是要借助于雙緩沖的概念。比如這個程序里,我們要實現使用鼠標在界面上繪制一個任意大小的矩形。這里需要兩張畫布,它們都是QPixmap實例,其中一個tempPix用來作為臨時緩沖區,當鼠標正在拖動矩形進行繪制時,將內容先繪制到tempPix上,然后將tempPix繪制到界面上;而另一個pix作為緩沖區,用來保存已經完成的繪制。當松開鼠標完成矩形的繪制后,則將tempPix的內容復制到pix上。為了繪制時不顯示拖影,而且保證以前繪制的內容不消失,那么在移動鼠標過程中,每繪制一次,都要在繪制這個矩形的原來的圖像上進行繪制,所以需要在每次繪制tempPix之前,先將pix的內容復制到tempPix上。因為這里有兩個QPixmap對象,也可以說有兩個緩沖區,所以稱之為雙緩沖繪圖。
代碼詳見《雙緩沖繪圖練習(20200217)》
九、圖形視圖框架
十、繪制波形圖?
?
參考資料:
1.??http://shouce.jb51.net/qt-beginning/15.html
2.?QT基礎:45---QPainter繪圖
3.?Qt之圖形(QPainterPath)
4.QT基礎:46---QPainter繪圖之QPen、QBrush、QFont工具
5.mouseMoveEvent中判斷鼠標狀態
6.QT基礎:47---QPainter繪圖之坐標轉換函數、視口和窗口
總結
以上是生活随笔為你收集整理的Qt学习笔记之2D绘图的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: \r与\n的区别,以及\r\n的用法
- 下一篇: 涂鸦板练习(20200214)