天天看点

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));
}