1. 程式人生 > >QT使用QPainter繪圖

QT使用QPainter繪圖

 使用QPainter繪圖

    要想在繪圖裝置上(一般是視窗部件)上繪圖,只需建立一個QPainter,再將指標傳到該裝置中,如:

    void MyWidget::paintEvent(QPaintEvent *event)

    {

        QPainter painter(this);

        ......

    }

    使用QPainter的draw...()函式,可以繪製各種各樣的形狀,讀者可以根據幫助文件學習以下基本的函式:

    drawPoint(),drawLine(),drawPolyline(),drawPoints(),drawLines(),drawPolygon(),drawRect(),drawRoundRect(),drawEllipse(),drawArc(),drawChord(),drawPie(),drawText()

    drawPixmap(),drawPath()

    繪製效果取決與QPainter的設定。一些值是從裝置中取得的,然而有的被初始化成預設值。三個主要的設定是畫筆,畫刷和字型。

    1.畫筆用來畫線和邊緣。包含顏色,寬度,線型,拐點風格以及連線風格;

    2.畫刷用來填充幾何圖形。一般由顏色和風格組成,但同時也可以是紋理或漸變;

    3字型用來繪製文字。一般有很多屬性,這裡不列舉。

    可以隨時呼叫QPen,QBrush或者QFont物件的setPen(),setBrush(), setFont()來修改這些設定。

    下面舉一些例子:

    首先在寫標頭檔案(這裡直接用系統給我生成的標頭檔案改了一下):

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void paintEvent(QPaintEvent *event);

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H



    然後寫對應的cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPainter>
#include <QRect>
#include <QBrush>
#include <QFont>
//用到什麼類就包含什麼標頭檔案

//這個MainWindow類是系統自動為我起的名字,實際操作中可自定義
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

//核心程式碼
void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);             // 建立QPainter一個物件

    // 畫一條直線
    QPen pen;
    pen.setColor(Qt::yellow);           // 設定畫筆為黃色
    painter.setPen(pen);                // 設定畫筆
    painter.drawLine(rect().topLeft(), rect().bottomRight());

    // 畫一個空心矩形
    pen.setColor(Qt::darkRed);
    painter.setPen(pen);
    painter.drawRect(QRect(1, 1, 100, 100));

    // 畫一個實心矩形
    QBrush bruch(Qt::FDiagPattern);     // 畫刷
    painter.setBrush(bruch);            // 設定畫刷
    painter.drawRect(QRect(105, 1, 100, 100));

    // 畫一個多點線
    pen.setColor(Qt::white);
    painter.setPen(pen);
    bruch.setStyle(Qt::NoBrush);        // 將畫刷設定成null
    painter.setBrush(bruch);
    static const QPointF points[4] = {QPointF(210.0, 1), QPointF(220.0, 50.3), QPointF(300, 100.4), QPointF(260.4, 120.0)};
    painter.drawPolyline(points, 4);

    // 畫多個點
    QPointF pointf[10];
    for (int i=0; i<10; ++i)
    {
        pointf[i].setX(2.0+i*10.0);
        pointf[i].setY(130.0);
    }
    painter.drawPoints(pointf, 10);

    // 畫多條線
    QLineF linef[5];
    for (int j=0; j<5; ++j)
    {
        linef[j].setP1(QPointF(110.9+j*10, 120.0));
        linef[j].setP2(QPointF(120.8+j*12, 200.0));
    }
    painter.drawLines(linef, 5);

    // 畫一個多邊形
    QPolygonF polygon;
    polygon << QPointF(200.0, 120.0) << QPointF(230.0, 130.0) << QPointF(260.0, 180.0) << QPointF(200.0, 200.0);
    bruch.setStyle(Qt::CrossPattern);
    painter.setBrush(bruch);
    painter.drawPolygon(polygon, Qt::WindingFill);

    // 畫一個圓角矩形
    QRectF rectangle(290.0, 110.0, 50, 50);
    bruch.setStyle(Qt::SolidPattern);
    painter.setBrush(bruch);
    painter.drawRoundedRect(rectangle, 20.0, 15.0);

    // 畫一個QString
    painter.drawText(50, 300, "Hello DevDiv!");

    //ps:下面這兩個有點綠啊。。。。。。如果擋住了上面的圖形的話就把他們兩個註釋掉吧
    //畫一個橢圓
    painter.setRenderHint(QPainter::Antialiasing, true);//啟用反走樣,告訴QPainter用不同顏色強度繪製邊框以減少視覺扭曲,這種扭曲一般
    //會在邊框轉換為畫素的時候發生。由此生成的結果是的到一條平滑的曲線
    painter.setPen(QPen(Qt::black, 12, Qt::DashDotDotLine, Qt::RoundCap));
    painter.setBrush(QBrush(Qt::green, Qt::SolidPattern));
    painter.drawEllipse(80, 80, 400, 240);

    //繪製三次貝塞爾曲線
    painter.setRenderHint(QPainter::Antialiasing, true);
    QPainterPath path;
    path.moveTo(80, 320);
    path.cubicTo(200, 80, 320, 80, 480, 320);
    painter.setPen(QPen(Qt::black, 8));
    painter.drawPath(path);
}

最後在主函式中顯示就可以了:
#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

    QPainterPath類可以通過連線基本的圖形元素來確定任意的向量形狀:直線,橢圓,多邊形,弧形,貝塞爾曲線和其他的繪製路徑。繪製路徑是基本的圖元,從這個意義上來說,任何圖形或圖形組合都可以用繪製路徑描述。

    路徑可以確定一個邊緣,由邊緣鎖定的區域可以用畫刷來填充。在現代應用中,漸變填充已成為單色填充的流行替代品。漸變填充利用顏色插值使得兩個或更多顏色之間平滑過渡。他們常被用來建立三維效果,Plastique和Ckeanlooks風格就是使用漸變來渲染QPushButton的。

    QT支援三種類型的漸變:線性漸變、錐形漸變和輻射漸變,下面是例子:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPainter>
#include <QPen>
#include <QBrush>
#include <QFont>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);//沒有使用event,去掉之後會有警告

    QPainter painter(this);//下面三個漸變位置重疊了,注意及時註釋以看到所有效果

    //線性漸變
    // 反走樣
    painter.setRenderHint(QPainter::Antialiasing, true);
    // 設定漸變色
    QLinearGradient linear(QPointF(80, 80), QPointF(150, 150));
    linear.setColorAt(0, Qt::black);
    linear.setColorAt(1, Qt::white);
    // 設定顯示模式
    linear.setSpread(QGradient::PadSpread);
    // 設定畫筆顏色、寬度
    painter.setPen(QPen(QColor(0, 160, 230), 2));
    // 設定畫刷填充
    painter.setBrush(linear);
    // 繪製橢圓
    painter.drawRect(QRect(40, 40, 180, 180));


    //錐形漸變
    // 反走樣
    painter.setRenderHint(QPainter::Antialiasing, true);
    // 設定漸變色
    QRadialGradient radial(110, 110, 50, 130, 130);
    radial.setColorAt(0, Qt::black);
    radial.setColorAt(1, Qt::white);
    // 設定顯示模式
    radial.setSpread(QGradient::ReflectSpread );
    // 設定畫筆顏色、寬度
    painter.setPen(QPen(QColor(0, 160, 230), 2));
    // 設定畫刷填充
    painter.setBrush(radial);
    // 繪製橢圓
    painter.drawRect(QRect(40, 40, 180, 180));

    //輻射漸變
    // 反走樣
    painter.setRenderHint(QPainter::Antialiasing, true);
    // 設定漸變色
    QConicalGradient conical(110, 110, 45);
    conical.setColorAt(0, Qt::black);
    conical.setColorAt(1, Qt::white);
    // 設定畫筆顏色、寬度
    painter.setPen(QPen(QColor(0, 160, 230), 2));
    // 設定畫刷填充
    painter.setBrush(conical);
    // 繪製橢圓
    painter.drawRect(QRect(40, 40, 180, 180));
}

    目前,我們提到了畫筆、畫刷和字型設定,另外QPainter還有其他影響圖形和文字的繪製方式設定,這裡簡單提及一點:

    當背景模式是Qt::QpaqueMode時,背景畫刷可以用來填充幾何圖形的背景、文字或者點陣圖