QPainter绘图
Qt的二维绘图功能是使用QPainter在绘图设备上绘图,绘图设备包括QWidget、QPixmap、QPainter、QImge等,作为Qt的三大基类之一的QWidget是最常见的绘图设备,QWideget类及其派生的子类,都有一个事件处理函数paintEvent(),在组件界面或者当前类的界面需要绘图时,就要重写这个绘图的事件处理函数,当有绘图指令时,系统会自动运行paintEvent()函数进行绘制图形。QPainter能在各种绘图设备上实现绘制图形功能的基本的类,如基于QWidget的各种Qt界面及组件的图形显示效果就是由QPainter实现。下面介绍QPainter、QPixmap的简单使用
一般绘画都会有一个画家、笔、颜色、刷子、绘画的板子纸张屏幕等,可以将QPainter创建的对象看做画家,绘画的板子、纸张、屏幕看做绘图的设备,即在哪个地方绘画,在界面上绘图,就需要重写绘图事件paintEvent()函数。
QPainter绘图主要是用QPainter的接口绘制各种图形,如点、直线、矩形、圆形、多边形、图片和文字等。绘制图形可以设置线条的风格(虚线、实线等)、线条的颜色,文字的特性,还有绘制图形的填充等,主要与QPen类、QBrush类、QFont类等有关。有关于这几个类这里不再介绍。
设置渲染:setRenderHint(),参数是枚举类型,如QPainter::SmoothPixmapTransform,可查看帮助文档
绘制文本:drawText()
注意:
如果指定绘图设备,也就是图片画在什么的板子,那个板子如果是当前窗体, 就是让当前窗体显示你所绘制的图片,那么一定要在paintEvent()函数中实现
如: painter(this)的就是指定绘制在窗体上,不是某个部件,如果指定QPainter对象的构造函数是this,只有在paintEvent()重写的函数中才能将图形绘制到窗体,绘制以后同时要调用update()进行窗体更新
如下代码:
void Father::paintEvent(QPaintEvent *event){
QPainter painter(this);
QPixmap pix(size());
pix.load("美女.png);
QRect rect(0,0,100 ,100);
painter.drawPixmap(rect,pix);
update();
}
例如:在别的函数中QPainter的对象的构造函数参数是this,那么图形不能绘制到窗体
以下的函数不能实现图形绘制到窗体并且显示
void Father::getRoundImages(){
QPainter painter(this);
QPixmap pix(size());
pix.load("美女.png);
QRect rect(0,0,100 ,100);
painter.drawPixmap(rect,pix);
}
(一)重写paintEvent()函数绘制基本图形
(1)在当前窗体绘制图形
详情,painter其参数是this,即绘图设备是当前界面,当前窗体(界面)的大小设置为(300,200),给画家设置画笔的颜色为红色setPen(QColor(Qt::red)),笔的宽度为20,pen.setWidth(20);,也可以定义一个笔,设置好笔的属性然后传给painter。绘制图形即调用对应的绘制图形的函数,如绘制直线drawLine()。
void painterTest::paintEvent(QPaintEvent *event)
{
//创建Qpainter对象
QPainter painter(this);
//painter.setPen(QColor(Qt::red));
QPen pen;
pen.setWidth(20);
pen.setColor(QColor(Qt::red));
painter.setPen(pen);
//绘制直线,效果如图一所示
painter.drawLine(0,0,width(),height());
//绘制圆形,效果如图2
painter.drawEllipse(width()/2,height()/2,100,100);
}
效果展示
图1
图2
(2)在指定区域进行绘制
void painterTest::paintEvent(QPaintEvent *event)
{
//创建Qpainter对象
QPainter painter(this);
//painter.setPen(QColor(Qt::blue));
QPen pen;
pen.setWidth(10);
pen.setColor(QColor(Qt::red));
painter.setPen(pen);
//界面中部定义矩形,将矩形作为绘图的区域
QRect rect(QPoint(width()/2-50,height()/2-50),QPoint(width()/2+50,height()/2+50));
//绘制直线,效果如图所示
painter.drawLine(rect.topLeft(),rect.bottomRight());
//绘制圆形
painter.drawEllipse(rect);
}
(2)使用QPainterPath类实现指定位置绘制图像
QPainterPath是绘制图形路径的类,也就是说,QPainter可以在QPainterPath指定一定的路径(范围)绘图
不同的部件填充图片有一些区别:QPushButon是将图片作为图标填充进去,QLabel可将图片直接填充到对象中
QPushButon对象调用setIcon()
QLabel对象调用setPixmap();
Pixmap pix;
pix.load(“…/esources/MainWindow/head_mask.png”);
ui.headLabel->setPixmap(pix);
(二)重写paintEvent绘制图片
QPixmap
QPixmap主要是用于绘图,针对屏幕显示而最佳化设计,QImage主要是为图像I/O、图片访问和像素修改而设计的。当图片小的情况下,直接用QPixmap进行加载,画图时无所谓,当图片大的时候如果直接用QPixmap进行加载,会占很大的内存,一般一张几十K的图片,用QPixmap加载进来会放大很多倍,所以一般图片大的情况下,用QImage进行加载,然后用QPixmap进行绘制,就可以减少很多资源
QPixmap pixmap(“…/美女1.png”);构造像素图(以传入的图片"美女.png"文件构造)
(1)文件图片进行绘制
void painterTest::paintEvent(QPaintEvent *event)
{
//创建Qpainter对象
QPainter painter(this);
QRect rect(QPoint(width()/2-50,height()/2-50),QPoint(width()/2+50,height()/2+50));
//根据项目中的图片绘制图片,效果如图
painter.drawPixmap(rect,QPixmap(tr("../美女1.png")));
}
效果图如下
(2)文件图片按比例进行绘制
QPixmap调用scaled()函数可以对像素图按比例进行缩放,并且指定缩放的方式
void painterTest::paintEvent(QPaintEvent *event)
{
//创建Qpainter对象,其参数是this,即绘图设备是当前界面
QPainter painter(this);
QPen pen;
pen.setWidth(20);
pen.setColor(QColor(Qt::blue));
painter.setPen(pen);
QRect rect(QPoint(width()/2-50,height()/2-50),QPoint(width()/2+50,height()/2+50));
//用传入的图片美女1.png构造像素图,
QPixmap pixmap("../美女1.png");
painter.drawPixmap(QRect(0,0,this->width()/2,this->height()/2),pixmap);
//像素图放大2倍
pixmap.scaled(2.0,2.0,Qt::IgnoreAspectRatio);
painter.drawPixmap(QRect(this->width()/2,this->height()/2,width(),height()),pixmap);
}
效果图如下
(三)QPainter绘图的坐标
以下示例是坐标的简单运用
void painterTest::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
//设置渲染,文本反锯齿
painter.setRenderHint(QPainter::TextAntialiasing);
QFont font;
font.setPointSize(10);
painter.setFont(font);
//绘制文本
painter.drawText(24, 0, width() - 24, height(), Qt::AlignLeft | Qt::AlignCenter, m_titleText);
painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
painter.save();
if (m_hasArrow) {
QPixmap pixmap;
pixmap.load(":/Resources?MainWindow/arrow.png");
QPixmap tmpPixmap(pixmap.size());
tmpPixmap.fill(Qt::transparent);
QPainter p(&tmpPixmap);
//设置渲染
p.setRenderHint(QPainter::SmoothPixmapTransform, true);
//translate是坐标系偏移,参数就是偏移量,这个坐标系就是绘图设备所在的坐标系
p.translate(pixmap.width() / 2, pixmap.height() / 2);
//rotate是顺时针选择坐标系,
p.rotate(m_rotation);
p.drawPixmap(0 - pixmap.width() / 2, 0 - pixmap.height() / 2,pixmap);
painter.drawPixmap(6, (height() - pixmap.height()) / 2, tmpPixmap);
//restore()恢复到painter之前的save()之前
painter.restore();
}
(四)绘制背景透明的像素图
使用QPixmap构造两个像素图,其中一张像素图背景透明
对象pix是图像大小为(80,50),这个图像加载了图片“girl.png",然后将pix作为像素图加载到第二张像素图img对象,img大小为(150,80),设置背景透明效果fill(Qt::transparent),然后Label对象加载第二张图片
效果如下:
void Widget::painterOther(){
//第一张最小的像素图
QPixmap pix(QSize(80,50));
QPainter painter(&pix);
painter.drawPixmap(0,0,QPixmap("../girl.png"));
//第二张像素图
QPixmap img(150,80);
img.fill(QColor(170, 170, 255));
img.fill(Qt::transparent);
QPainter draimg(&img);
draimg.drawPixmap(0,0,pix);
//Label填充第二张像素图
ui->label->setPixmap(img);
}
效果图:设置像素图背景透明前
效果图:设置像素图背景透明后