关于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();
}
效果如下: