除了繪製圖形之外,還可使用QPainter::darwText()函數來繪製文字,也可使用QPainter::setFont()設置文字所使用的字體,使用QPainter::fontInfo()函數能夠獲取字體的信息,它返回QFontInfo類對象。在繪製文字時會默認使用抗鋸齒。php
下面仍然在上一節的程序中進行代碼演示,更改paintEvent()的內容以下:linux
void Widget::paintEvent(QPaintEvent *) { QPainter painter(this); painter.drawText(100, 100, "qter.org-yafeilinux"); }
這樣就在(100, 100)的位置繪製了一個字符串。效果以下圖所示。c++
咱們先到QPainter的幫助文檔頁面,而後查看drawText()函數的重載形式,找到:api
QPainter::drawText ( const QRectF & rectangle, int flags, const QString & text, QRectF * boundingRect = 0 )
下面來看一個例子。爲了更明顯地看到文字在指定矩形中的位置,咱們繪製出這個矩形。將paintEvent()函數更改以下:函數
void Widget::paintEvent(QPaintEvent *) { QPainter painter(this); //設置一個矩形 QRectF rect(50, 50, 300, 200); //爲了更直觀地看到字體的位置,咱們繪製出這個矩形 painter.drawRect(rect); painter.setPen(QColor(Qt::red)); //這裏先讓字體水平居中 painter.drawText(rect, Qt::AlignHCenter, "yafeilinux"); }
如今運行程序,效果以下圖所示。字體
可用的對齊方式以下圖所示。優化
爲了繪製漂亮的文字,可使用QFont類來設置文字字體。你們也能夠先在幫助文檔中查看該類的介紹。下面將最經常使用的一些設置進行演示。ui
將paintEvent()函數更改以下:this
void Widget::paintEvent(QPaintEvent *) { QPainter painter(this); //設置一個矩形 QRectF rect(50, 50, 300, 200); //爲了更直觀地看到字體的位置,咱們繪製出這個矩形 painter.drawRect(rect); painter.setPen(QColor(Qt::red)); //這裏先讓字體水平居中 painter.drawText(rect, Qt::AlignHCenter, "yafeilinux"); //使用字體 QFont font("宋體", 15, QFont::Bold, true); //設置下劃線 font.setUnderline(true); //設置上劃線 font.setOverline(true); //設置字母大小寫 font.setCapitalization(QFont::SmallCaps); //設置字符間的間距 font.setLetterSpacing(QFont::AbsoluteSpacing, 10); //使用字體 painter.setFont(font); painter.setPen(Qt::blue); painter.drawText(120, 80, tr("yafeilinux")); painter.translate(50, 50); painter.rotate(90); painter.drawText(0, 0, tr("helloqt")); }
這裏建立了QFont字體對象,使用的構造函數爲QFont::QFont ( const QString & family,int pointSize = -1, int weight = -1, bool italic = false ),第一個參數設置字體的family屬性,這裏使用的字體族爲宋體,可使用QFontDatabase類來獲取所支持的全部字體;第二個參數是點大小,默認大小爲12;第三個參數爲weight屬性,這裏使用了粗體;最後一個屬性設置是否使用斜體。而後咱們又使用了其餘幾個函數來設置字體的格式,最後調用setFont()函數來使用該字體,並使用drawText()函數的另外一種重載形式在點(120, 80)繪製了文字。後面又將座標系統平移並旋轉,而後再次繪製了文字。運行程序,效果以下圖所示。spa
若是要繪製一個複雜的圖形,那麼可使用QPainterPath類,而後使用QPainter::drawPath()來進行繪製。QPainterPath類爲繪製操做提供了一個容器,能夠用來建立圖形而且重複使用。一個繪圖路徑就是由多個矩形、橢圓、線條或者曲線等組成的對象,一個路徑能夠是封閉的,例如矩形和橢圓;也能夠是非封閉的,例如線條和曲線。
下面看一個例子:添加一個橢圓和一根線在圖形路徑裏。依然在前面的項目中進行講解。更改paintEvent()函數以下:
void Widget::paintEvent(QPaintEvent *) { //添加一個橢圓和一根線在圖形路徑裏 QPainterPath path; path.addEllipse(100, 100, 50, 50); //添加一個圓心爲(100,100),橫縱半徑都爲50的橢圓 path.lineTo(200, 200); //添加一根從當前位置到(200,200)的線 QPainter painter(this); painter.setPen(Qt::blue); painter.setBrush(Qt::red); painter.drawPath(path); }
當建立一個QPainterPath對象後,可使用lineTo()、arcTo()、cubicTo()和quadTo()等函數將直線或者曲線添加到路徑中。運行程序,效果以下圖所示。
若是隻是簡單的將幾個圖形拼接在一塊兒,其實徹底沒有必要用路徑,之因此要引入路徑,就是由於它的一個很是有用的功能:複製圖形路徑。更改paintEvent()函數以下:
void Widget::paintEvent(QPaintEvent *) { //添加一個橢圓和一根線在路徑裏 QPainterPath path; path.addEllipse(100, 100, 50, 50); //添加一個圓心爲(100,100),橫縱半徑都爲50的橢圓 path.lineTo(200, 200); //添加一根從當前位置到(200,200)的線 QPainter painter(this); painter.setPen(Qt::blue); painter.setBrush(Qt::red); painter.drawPath(path); //複製圖形路徑 QPainterPath path2; path2.addPath(path); path2.translate(100,0); painter.drawPath(path2); }
如今運行程序,效果以下圖所示。
能夠看到,對於已經繪製好的路徑,能夠很是簡單地進行重複繪製。
咱們先來看一個例子,將paintEvent()函數更改以下:
void Widget::paintEvent(QPaintEvent *) { QPainterPath path; path.lineTo(100, 100); path.lineTo(200, 100); QPainter painter(this); painter.drawPath(path); }
程序運行效果以下圖所示。
能夠看到,建立路徑後,默認是從(0, 0)點開始繪製的,當繪製完第一條直線後當前位置是(100, 100)點,從這裏開始繪製第二條直線。繪製完第二條直線後,當前位置是(200, 100)。
咱們也能夠使用moveTo()函數來改變當前點的位置。例如將paintEvent()函數更改以下:
void Widget::paintEvent(QPaintEvent *) { QPainterPath path; path.addRect(50, 50, 40, 40); //移動到(100, 100)點 path.moveTo(100, 100); path.lineTo(200, 200); QPainter painter(this); painter.drawPath(path); }
這樣當繪製完矩形之後,就會移動到(100, 100)點進行後面的繪製。程序運行效果以下圖所示
Qt提供了四個類來處理圖像數據:QImage、QPixmap、QBitmap和QPicture,它們都是經常使用的繪圖設備。其中QImage主要用來進行I/O處理,它對I/O處理操做進行了優化,並且能夠用來直接訪問和操做像素;QPixmap主要用來在屏幕上顯示圖像,它對在屏幕上顯示圖像進行了優化;QBitmap是QPixmap的子類,用來處理顏色深度爲1的圖像,即只能顯示黑白兩種顏色;QPicture用來記錄並重演QPainter命令。這一節咱們只講解QPixmap。
(1)此次咱們從新建立一個Qt Widgets應用,項目名稱爲mypixmap,在類信息頁面,將基類選擇爲QDialog,類名使用默認的Dialog便可。
(2)而後在源碼目錄中複製一張圖片,好比這裏是一張logo.png圖片,以下圖所示。
(3)在dialog.h文件中添加劇繪事件處理函數的聲明:
protected: void paintEvent(QPaintEvent *);
(4)到dialog.cpp文件中先添加頭文件包含#include <QPainter>,而後添加函數的定義:
void Widget::paintEvent(QPaintEvent *) { QPainter painter(this); QPixmap pix; pix.load("../mypixmap/logo.png"); painter.drawPixmap(0, 0, 80, 100, pix); }
這裏使用了相對路徑,由於Qt Creator默認是使用影子構建,即編譯生成的文件在build-mypixmap-Desktop_Qt_5_8_0_MinGW_32bit-Debug這樣的目錄裏面,而這個目錄就是當前目錄,因此源碼目錄就是其上級目錄了。你們能夠根據本身的實際狀況來更改路徑,也可使用絕對路徑,不過最好使用資源文件來存放圖片。drawPixmap()函數在給定的矩形中來繪製圖片,這裏矩形的左上角頂點爲(0, 0)點,寬80,高100,若是寬高跟圖片的大小比例不一樣,默認會拉伸圖片。運行效果以下圖所示。
QPainter類中的translate()函數實現座標原點的改變,改變原點後,此點將會成爲新的原點(0,0)。下面來看一個例子。在paintEvent()函數中繼續添加以下代碼:
//將(100,100)設爲座標原點 painter.translate(100, 100); painter.drawPixmap(0, 0, 80, 100, pix);
這裏將(100,100)設置爲了新的座標原點,因此下面在(0,0)點貼圖,就至關於在之前的(100,100)點貼圖。運行程序,效果以下圖所示。
咱們可使用QPixmap類中的scaled()函數來實現圖片的放大和縮小。在paintEvent()函數中繼續添加以下代碼:
//得到之前圖片的寬和高 qreal width = pix.width(); qreal height = pix.height(); //將圖片的寬和高都縮小,而且在給定的矩形內保持寬高的比值不變 pix = pix.scaled(width, height,Qt::KeepAspectRatio); painter.drawPixmap(90, 90, pix);
其中參數Qt::KeepAspectRatio,是圖片縮放的方式。能夠將鼠標指針放到該代碼上,按下F1鍵查看其幫助了,以下圖所示。
這裏有三個值,只看其示例圖片就可大體明白,Qt::IgnoreAspectRatio是不保持圖片的寬高比;Qt::KeepAspectRatio是在給定的矩形中保持寬高比;最後一個也是保持寬高比,但可能超出給定的矩形。這裏給定的矩形是由咱們顯示圖片時給定的參數決定的,例如painter.drawPixmap(0,0,100,100,pix);就是在以(0,0)點爲起始點的寬和高都是100的矩形中。運行程序效果以下圖所示。
旋轉使用的是QPainter類的rotate()函數,它默認是以原點爲中心進行旋轉的。若是要改變旋轉的中心,可使用前面講到的translate()函數完成。在paintEvent()函數中繼續添加以下代碼:
//讓圖片的中心做爲旋轉的中心 painter.translate(40, 50); painter.rotate(90); //順時針旋轉90度 painter.translate(-40,-50); //使原點復原 painter.drawPixmap(100, 100, 80, 100, pix);
這裏必須先改變旋轉中心,而後再旋轉,而後再將原點復原,才能達到想要的效果。運行程序,以下圖所示。
實現圖片的扭曲,是使用的QPainter類的shear(qreal sh,qreal sv)函數完成的。它有兩個參數,前面的參數實現橫向變形,後面的參數實現縱向變形。當它們的值爲0時,表示不扭曲。在paintEvent()中繼續添加以下代碼:
painter.shear(0.5, 0); //橫向扭曲 painter.drawPixmap(100, 0, 80, 100, pix);
運行效果以下圖所示。
QPainter提供了複合模式(Composition Modes)來定義如何完成數字圖像的複合,即如何將源圖像的像素和目標圖像的像素進行合併。QPainter提供的經常使用複合模式及其效果以下圖所示。 其中普通的類型是SoiirceOver(一般被稱爲alpha混合),就是正在繪製的源像素混合在已經繪製的目標像素上,源像素的alpha份量定義了它的透明度,這樣源圖像就會以透明效果在目標圖像上進行顯示。當設置了複合模式,它就會應用到全部的繪圖操做中,例如畫筆、畫刷、漸變和pixmap/image繪製等。
實例:
void Widget::paintEvent(QPaintEvent *event) { QPainter painter; QImage image(400, 300, QImage::Format_ARGB32_Premultiplied); painter.begin(&image); painter.setBrush(Qt::green); painter.drawRect(100, 50, 200, 200); painter.setBrush(QColor(0, 0, 255, 150)); painter.drawRect(50, 0, 100, 100); painter.setCompositionMode(QPainter::CompositionMode_SourceIn); painter.drawRect(250, 0, 100, 100); painter.setCompositionMode(QPainter::CompositionMode_DestinationOver); painter.drawRect(50, 200, 100, 100); painter.setCompositionMode(QPainter::CompositionMode_Xor); painter.drawRect(250, 200, 100, 100); painter.end(); painter.begin(this); painter.drawImage(0, 0, image); }
這裏先在Qlmage上繪製了一個矩形,而後又在這個矩形的4個角分別繪製了4個小矩形,每一個小矩形都使用了不一樣的複合模式,而且使用了半透明的顏色進行填充。 第一個小矩形沒有明確指定複合模式,它默認使用的是SourceOver模式。運行效果以下圖所示。
參考: