繪圖設備是繼承QPainterDevice
的類。QPaintDevice
就是可以進行繪製的類,也就是說,QPainter
能夠在任何QPaintDevice
的子類上進行繪製。如今,Qt 提供了若干這樣的類:數組
在 Qt5 中,QGLPixelBuffer
已經被廢棄。本章咱們關注的是QPixmap
、QBitmap
、QImage
和QPicture
這幾個類。另外的部分,QWidget
就是全部組件的父類,咱們已經在前面的章節中使用過,這裏再也不贅述。QGLWidget
和QGLFramebufferObject
,顧名思義,就是關於 OpenGL 的相關類。在 Qt 中,咱們能夠方便地結合 OpenGL 進行繪製。因爲這部分須要牽扯到 OpenGL 的相關內容,如今也再也不深刻。在咱們選擇的幾個類中,大多與圖像密切相關。svg
QPixmap
專門爲圖像在屏幕上的顯示作了優化;QBitmap
是QPixmap
的一個子類,它的色深限定爲1,你可使用QPixmap
的isQBitmap()
函數來肯定這個QPixmap
是否是一個QBitmap
。QImage
專門爲圖像的像素級訪問作了優化。QPicture
則能夠記錄和重現QPainter
的各條命令。下面咱們將分兩部分介紹這四種繪圖設備。函數
QPixmap
繼承了QPaintDevice
,所以,你可使用QPainter
直接在上面繪製圖形。QPixmap
也能夠接受一個字符串做爲一個文件的路徑來顯示這個文件,好比你想在程序之中打開 png、jpeg 之類的文件,就可使用QPixmap
。使用QPainter::drawPixmap()
函數能夠把這個文件繪製到一個QLabel
、QPushButton
或者其餘的設備上面。正如前面所說的那樣,QPixmap
是針對屏幕進行特殊優化的,所以,它與實際的底層顯示設備息息相關。注意,這裏說的顯示設備並非硬件,而是操做系統提供的原生的繪圖引擎。因此,在不一樣的操做系統平臺下,QPixmap
的顯示可能會有所差異。性能
QPixmap
提供了靜態的grabWidget()
和grabWindow()
函數,用於將自身圖像繪製到目標上。同時,在使用QPixmap
時,你能夠直接使用傳值的形式,不須要傳指針,由於QPixmap
提供了「隱式數據共享」。關於這一點,咱們會在之後的章節中詳細描述。簡單來講,就是通常對於大型數據(圖像無疑就是這種「大型數據」),爲性能起見,一般會採用傳指針的方式,可是因爲QPixmap
內置了隱式數據共享,因此只要知道傳遞QPixmap
。優化
前面說過,QBitmap
繼承自QPixmap
,所以具備QPixmap
的全部特性。不一樣之處在於,QBitmap
的色深始終爲 1。色深這個概念來自計算機圖形學,是指用於表現顏色的二進制的位數。咱們知道,計算機裏面的數據都是使用二進制表示的。爲了表示一種顏色,咱們也會使用二進制。好比咱們要表示 8 種顏色,須要用 3 個二進制位,這時咱們就說色深是 3。所以,所謂色深爲 1,也就是使用 1 個二進制位表示顏色。1 個位只有兩種狀態:0 和 1,所以它所表示的顏色就有兩種,黑和白。因此說,QBitmap
其實是隻有黑白兩色的圖像數據。因爲QBitmap
色深小,所以只佔用不多的存儲空間,因此適合作光標文件和筆刷。this
下面咱們來看同一個圖像文件在QPixmap
和QBitmap
下的不一樣表現:操作系統
void paintEvent(QPaintEvent *) { QPainter painter(this); QPixmap pixmap("qt-logo.png"); QBitmap bitmap("qt-logo.png"); painter.drawPixmap(10, 10, 250, 125, pixmap); painter.drawPixmap(270, 10, 250, 125, bitmap); QPixmap whitePixmap("qt-logo-white.png"); QBitmap whiteBitmap("qt-logo-white.png"); painter.drawPixmap(10, 140, 250, 125, whitePixmap); painter.drawPixmap(270, 140, 250, 125, whiteBitmap); }
先來看一下運行結果:指針
這裏咱們給出了兩張 png 圖片。qt-logo.png 具備透明背景,qt-logo-white.png 具備白色背景。咱們分別使用QPixmap
和QBitmap
來加載它們。注意看它們的區別:白色的背景在QBitmap
中消失了,而透明色在QBitmap
中轉換成了黑色(「黑色」,記住,QBitmap
只有兩種顏色:黑色和白色);其餘顏色則是使用點的疏密程度來體現的。code
QPixmap
使用底層平臺的繪製系統進行繪製,沒法提供像素級別的操做,而QImage
則是使用獨立於硬件的繪製系統,其實是本身繪製本身,所以提供了像素級別的操做,而且可以在不一樣系統之上提供一個一致的顯示形式。orm
QImage
與QPixmap
相比,最大的優點在於可以進行像素級別的操做。咱們經過上面的示意圖能夠看到,咱們聲明一個 3 x 3 像素的QImage
對象,而後利用setPixel()
函數進行顏色的設置。你能夠把QImage
想象成一個 RGB 顏色的二維數組,記錄了每一像素的顏色。值得注意的是,在QImage
上進行繪製時,不能使用QImage::Format_Indexed8
這種格式。
最後一種QPicture
是平臺無關的,所以它可使用在多種設備之上,好比 svg、pdf、ps、打印機或者屏幕。回憶下咱們曾經說的QPaintDevice
,其實是說能夠由QPainter
進行繪製的對象。QPicture
使用系統分辨率,而且能夠調整QPainter
來消除不一樣設備之間的顯示差別。若是咱們要記錄下QPainter
的命令,首先要使用QPainter::begin()
函數,將QPicture
實例做爲參數傳遞進去,以便告訴系統開始記錄,記錄完畢後使用QPainter::end()
命令終止。代碼示例以下:
QPicture picture; QPainter painter; painter.begin(&picture); // 在 picture 進行繪製 painter.drawEllipse(10, 20, 80, 70); // 繪製一個橢圓 painter.end(); // 繪製完成 picture.save("drawing.pic"); // 保存 picture
若是咱們要重現命令,首先要使用 QPicture::load() 函數進行裝載:
QPicture picture; picture.load("drawing.pic"); // 加載 picture QPainter painter; painter.begin(&myImage); // 在 myImage 上開始繪製 painter.drawPicture(0, 0, picture); // 在 (0, 0) 點開始繪製 picture painter.end(); // 繪製完成
咱們也能夠直接使用QPicture::play()
進行繪製。這個函數接受一個QPainter
對象,也就是進行繪製的畫筆。