Qt开发之绘图与更新绘图

关于Qt的绘画,简单介绍吧,一些常用的知识点

Qt中的所有的图都是画出来的,例如我们的按钮,窗口,标签上的图

画图需要两个东西

1.画家QPainter

2.画板QPaintDevice(常见的控件,按钮label窗口)

Qt绘图机制为屏幕显示和打印显示提供了统一的API接口,主要有三部分组成:

(1)QPainter类,提供了画图的各种接口,可方便地绘制各种各样的图形

(2)QPaintDevice类,提供可用于画图的控件,及画图容器

(3)QPainterEngine类,抽象类,提供了QPainter类如何在指定的平台上给

指定的设备绘画的抽象接口,对于开发者而言,一般不会用到

QPainter类(画家)------->QPainterEngine类(翻译)------->QPainterEngine类(设备)

 

主要讲一下QPainter类的用法方法等

QPainter painter(this);

1.画线段 - drawLine()

给定两个点的坐标画一条线段

painter.drawLine(x1, y1, x2, y2);

2.画多条线段 - drawLines()

给定 N 个点,第 1 和第 2 个点连成线,第 3 和第 4 个点连成线,……,N 个点练成 (N+1)/2 条线,如果 N 是奇数,第 N 个点和 (0,0) 连成线。

static const QPointF points[4] = {QPointF(x1, y1),QPointF(x2, y2),QPointF(x3, y3),QPointF(x4, y4)};
painter.drawLines(points, 2); // 4 个点连成 2 条线

3.画折线- drawPolyline()

给定 N 个点,第 1 和第 2 个点连成线,第 2 和第 3 个点连成线,……,第 N-1 和第 N 个点连成线,N 个点共连成 N-1 条线。

static const QPointF points[4] = {QPointF(x1, y1),QPointF(x2, y2),QPointF(x3, y3),QPointF(x4, y4)};
painter.drawPolyline(points, 4);

4.画多边形 - drawPolygon()

给定 N 个点,第 1 和第 2 个点连成线,第 2 和第 3 个点连成线,……,第 N-1 和第 N 个点连成线,第 N 个点和第 1 个点连接成线形成一个封闭的多边形。

static const QPointF points[4] = {QPointF(x1, y1),QPointF(x2, y2),QPointF(x3, y3),QPointF(x4, y4)};
painter.drawPolygon(points, 4);

5.画矩形 - drawRect()

给定矩形左上角的坐标和矩形的长、宽就可以绘制矩形了。

painter.drawRect(x, y, width, height);

6.画圆角矩形- drawRoundRect() & drawRoundedRect()

绘制圆角矩形有 2 个方法:drawRoundRect() 和 drawRoundedRect(),需要给定圆角矩形左上角的坐标、长、宽、圆角的半径。

当 drawRoundedRect() 中第 7 个参数 Qt::SizeMode 为 Qt::RelativeSize 时,表示圆角半径的单位是百分比,取值范围是 [0, 100],此时 drawRoundedRect() 等价于 drawRoundRect(),其实底层是用这个百分比和对应边长的一半相乘得到圆角的半径(单位是像素)。Qt::SizeMode 为 Qt::AbsoluteSize 时,表示圆角半径的单位是像素。

painter.drawRoundRect(0, 0, 100, 100, 50, 50); // 50%, 50%
painter.drawRoundedRect(130, 0, 100, 100, 50, 50, Qt::AbsoluteSize); // 50px, 50px
painter.drawRoundedRect(260, 0, 100, 100, 100, 100, Qt::RelativeSize); // 100%, 100%

7.画椭圆,圆 - drawEllipse()

给定椭圆的包围矩形(bounding rectangle),使用 drawEllipse() 绘制椭圆。圆是特殊的椭圆,椭圆有两个焦点,这两个焦点合为一个的时候就是一个正圆了,当包围矩形是正方形时,drawEllipse() 绘制的就是圆。

当然,画圆的方法很多,上面我们就使用了 drawPolygon(),drawRounedRect() 的方法画圆,不过从语义上来说,用 drawEllipse() 来画圆显得更舒服一些。

painter.drawEllipse(0, 0, 200, 100); // 椭圆
painter.drawEllipse(230, 0, 100, 100); // 圆

8.画弧,弦,饼图 - drawArc(), drawChord(), drawPie()

画弧使用 drawArc()   画弦使用 drawChord()   画饼图用 drawPie()

把这三个函数放在一起介绍,因为它们的参数都一样,而且 arc, chord, pie 外形也有很多相似之处,不太常用

painter.drawArc(const QRectF & rectangle, int startAngle, int spanAngle)
painter.drawPie(const QRectF & rectangle, int startAngle, int spanAngle)
painter.drawChord(const QRectF & rectangle, int startAngle, int spanAngle)

9.绘制 QPixmap - drawPixmap()

Pixmap 的绘制有下面四种方式(每种方式都有几个重载的函数,没有全部列举出来):

(1)在指定位置绘制 pixmap,pixmap 不会被缩放

/* pixmap 的左上角和 widget 上 x, y 处重合 */
painter.drawPixmap(int x, int y, const QPixmap & pixmap)
或者painter.drawPixmap(const QPointF &point, const QPixmap &pixmap)

(2)在指定的矩形内绘制 pixmap,pixmap 被缩放填充到此矩形内

/* target 是 widget 上要绘制 pixmap 的矩形区域 */
painter.drawPixmap(int x, int y, int width, int height, const QPixmap &pixmap)
或者painter.drawPixmap(const QRect &target, const QPixmap &pixmap)

(3)绘制 pixmap 的一部分,可以称其为 sub-pixmap

/* source 是 sub-pixmap 的 rectangle */
painter.drawPixmap(const QPoint &point, const QPixmap &pixmap, const QRect &source)
或者painter.drawPixmap(const QRect &target, const QPixmap &pixmap, const QRect &source)
或者painter.drawPixmap(int x, int y, const QPixmap &pixmap, 
                          int sx, int sy, int sw, int sh)

(4)平铺绘制 pixmap,水平和垂直方向都会同时使用平铺的方式

void QPainter::drawTiledPixmap(const QRect &rectangle, 
                               const QPixmap &pixmap, 
                               const QPoint &position = QPoint())
或者void QPainter::drawTiledPixmap(int x, int y, int width, int height, 
                               const QPixmap & pixmap, 
                               int sx = 0, int sy = 0)

10.绘制文本 - drawText()

绘制文本非常常见,QPushButton,QLabel,QTableView 等等都得用,看似简单,其实里面有很多的学问,要掌握好还是挺不容易的。

文本的绘制有两种方式:

(1)在指定位置绘制文本,不会自动换行

painter.drawText(int x, int y, const QString &text)

(2)在指定的矩形内绘制文本,设置 flags 能够实现自动换行,对齐等

void QPainter::drawText(const QRect& rectangle, 
                        int flags, 
                        const QString &text,
                        QRect *boundingRect = 0)

11.画笔 - QPen

QPen 用来绘制轮廓,可以设置画笔的粗细,颜色,填充方式(Brush),端点的样式(Cap Style),相交的样式(Join Style),Style(SolidLine, DashLine, DotLine 等)。

QPen pen1(Qt::darkGray, 20, Qt::SolidLine, Qt::RoundCap, Qt::MiterJoin);//设置QPen的属性参数
painter.setPen(pen1);//设置为画家的画笔

12.画刷 - QBrush

QBrush 是用来填充图形用的

QPixmap pixmap(":/resources/Paint-Base-Bufferfly.png");
QBrush brush(pixmap);
painter.setBrush(brush);

 

 

 

下面写一个代码做一下实战练习,包括如何使用更新绘画。

绘图的一些操作,以及鼠标点击之后图片显示至该点的位置,代码如下:

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QPainter>
#include <QMouseEvent>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    i=0;
    j=0;
}

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

void Widget::paintEvent(QPaintEvent *event){
    qDebug()<<"###"<<endl;

    //绘图一定需要在这个函数中绘图
    QPainter p(this);//定义一个画家,并且制定了绘图设备this
    //画一幅画
    p.drawPixmap(i,j,150,100,QPixmap("../images/paint.jpg"));
    QPen pen;//一支笔
    pen.setColor(Qt::red);//设置笔的颜色
    p.setPen(pen);//将笔给到画家
    p.drawLine(QLine(0,0,this->width(),this->height()));//画一根线
    p.drawLine(QLine(0,this->height(),this->width(),0));//画一根线
    static const QPointF points1[4]={
        QPointF(20,100),QPointF(100,20),QPointF(20,300),QPointF(300,20)

    };//定义要连成多条线段的点
    p.drawLines(points1,2);//4个点连成2条线
    static const QPointF points2[4]={
        QPointF(30,100),QPointF(100,30),QPointF(30,300),QPointF(300,30)

    };//定义要连成折线的点
    p.drawPolyline(points2, 4);//画一条折线
    static const QPointF points3[4]={
        QPointF(20,100),QPointF(40,100),QPointF(40,300),QPointF(20,300)
    };//定义要连成多边形的点
    p.drawPolygon(points3,4);//画一个多边形

    p.drawText(0,0,"绘图准备好了吗");//绘画文字
    p.drawEllipse(0,0,this->width(),this->height());//画一个矩形,在0,0坐标宽高设置好的矩形类画椭圆
}

//新建鼠标点击事件,进行更新绘图
void Widget::mousePressEvent(QMouseEvent *event){
    i = event->x();
    j = event->y();
    //刷新绘图
    this->update();

}

 效果如下:

  • 2
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Demo.demo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值