教程十一 绘制简单图形(合辑)

来源:互联网 发布:mac ctrl f5 编辑:程序博客网 时间:2024/05/21 17:14

原来csdn限制新手每天只可以写5篇blog,这次就把几篇放一起吧.

 

(1)原文教程十一 绘制简单图形

 

说明:以后使用的环境为基于Qt 4.6的Qt Creator 1.3.0 windows版本

本文介绍在窗口上绘制最简单的图形的方法。

1.新建Qt4 Gui Application工程,我这里使用的工程名为painter01,选用QDialog作为Base class

2.在dialog.h文件中声明重绘事件函数void paintEvent(QPaintEvent *);

3.在dialog.cpp中添加绘图类QPainter的头文件包含#include <QPainter>

4.在下面进行该函数的重定义。

void Dialog::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.drawLine(0,0,100,100);
}

其中创建了QPainter类对象,它是用来进行绘制图形的,我们这里画了一条线Line,其中的参数为线的起点(0,0),和终点(100,100)。这里的数值指的是像素,详细的坐标设置我们以后再讲,这里知道(0,0)点指的是窗口的左上角即可。运行效果如下:

5.在qt的帮助里可以查看所有的绘制函数,而且下面还给出了相关的例子。

6.我们下面将几个知识点说明一下,帮助大家更快入门。

将函数改为如下:

void Dialog::paintEvent(QPaintEvent *)
{
    QPainter painter(this);

    QPen pen; //画笔
    pen.setColor(QColor(255,0,0));
    QBrush brush(QColor(0,255,0,125)); //画刷

    painter.setPen(pen); //添加画笔
    painter.setBrush(brush); //添加画刷
    painter.drawRect(100,100,200,200); //绘制矩形
}

这里的pen用来绘制边框,brush用来进行封闭区域的填充,QColor类用来提供颜色,我们这里使用了rgb方法来生成颜色,即(red,green,blue),它们取值分别是0-255,例如(255,0,0)表示红色,而全0表示黑色,全255表示白色。后面的(0,255,0,125),其中的125是透明度(alpha)设置,其值也是从0到255,0表示全透明。最后将画笔和画刷添加到painter绘制设备中,画出图形。这里的Rect是长方形,其中的参数为(100,100)表示起始坐标,200,200表示长和宽。效果如下:

7.其实画笔和画刷也有很多设置,大家可以查看帮助。

QPainter painter(this);

    QPen pen(Qt::DotLine);
    QBrush brush(Qt::blue);
    brush.setStyle(Qt::HorPattern);

    painter.setPen(pen);
    painter.setBrush(brush);
    painter.drawRect(100,100,200,200);

这里我们设置了画笔的风格为点线,画刷的风格为并行横线,效果如下:

在帮助里可以看到所有的风格。


我们这里用了Qt::blue,Qt自定义的几个颜色如下:

8.画弧线,这是帮助里的一个例子。

QRectF rectangle(10.0, 20.0, 80.0, 60.0); //矩形
     int startAngle = 30 * 16;     //起始角度
     int spanAngle = 120 * 16;   //跨越度数

     QPainter painter(this);
     painter.drawArc(rectangle, startAngle, spanAngle);

这里要说明的是,画弧线时,角度被分成了十六分之一,就是说,要想为30度,就得是30*16。它有起始角度和跨度,还有位置矩形,要想画出自己想要的弧线,就要有一定的几何知识了。这里就不再祥述。

 

 

 

(2)原文教程十二 渐变填充

在qt中提供了三种渐变方式,分别是线性渐变,圆形渐变和圆锥渐变。如果能熟练应用它们,就能设计出炫目的填充效果。


线性渐变:

1.更改函数如下:

void Dialog::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QLinearGradient linearGradient(100,150,300,150);
    //从点(100,150)开始到点(300,150)结束,确定一条直线
    linearGradient.setColorAt(0,Qt::red);
    linearGradient.setColorAt(0.2,Qt::black);
    linearGradient.setColorAt(0.4,Qt::yellow);
    linearGradient.setColorAt(0.6,Qt::white);
    linearGradient.setColorAt(0.8,Qt::green);
    linearGradient.setColorAt(1,Qt::blue);
    //将直线开始点设为0,终点设为1,然后分段设置颜色
    painter.setBrush(linearGradient);
    painter.drawRect(100,100,200,100);
    
//绘制矩形,线性渐变线正好在矩形的水平中心线上
}

效果如下:

圆形渐变:

1.更改函数内容如下:

   QRadialGradient radialGradient(200,100,100,200,100);
   //其中参数分别为圆形渐变的圆心(200,100),半径100,和焦点(200,100)
    //这里让焦点和圆心重合,从而形成从圆心向外渐变的效果

    radialGradient.setColorAt(0,Qt::black);
    radialGradient.setColorAt(1,Qt::yellow);
    //渐变从焦点向整个圆进行,焦点为起始点0,圆的边界为1
    QPainter painter(this);
    painter.setBrush(radialGradient);
    painter.drawEllipse(100,0,200,200);
   //绘制圆,让它正好和上面的圆形渐变的圆重合

效果如下:


 

2.要想改变填充的效果,只需要改变焦点的位置和渐变的颜色位置即可。

改变焦点位置:QRadialGradient radialGradient(200,100,100,100,100);

效果如下:


 

锥形渐变:

1.更改函数内容如下:

//圆锥渐变
    QConicalGradient conicalGradient(50,50,0);
    //圆心为(50,50),开始角度为0
    conicalGradient.setColorAt(0,Qt::green);
    conicalGradient.setColorAt(1,Qt::white);
   //从圆心的0度角开始逆时针填充
    QPainter painter(this);
    painter.setBrush(conicalGradient);
    painter.drawEllipse(0,0,100,100);

效果如下:


2.可以更改开始角度,来改变填充效果

QConicalGradient conicalGradient(50,50,30);

开始角度设置为30度,效果如下:


其实三种渐变的设置都在于焦点和渐变颜色的位置,如果想设计出漂亮的渐变效果,还要有美术功底啊!

 

(3)原文教程十三  绘制文字

 

接着上一次的教程,这次我们学习在窗体上绘制文字。

1.绘制最简单的文字。

我们更改重绘函数如下:

void Dialog::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.drawText(100,100,"yafeilinux");

}

我们在(100,100)的位置显示了一行文字,效果如下。

2.为了更好的控制字体的位置。我们使用另一个构造函数。在帮助里查看drawText,如下。


这里我们看到了构造函数的原型和例子。其中的flags参数可以控制字体在矩形中的位置。我们更改函数内容如下。

void Dialog::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QRectF ff(100,100,300,200);

    //设置一个矩形
    painter.drawRect(ff);
    //为了更直观地看到字体的位置,我们绘制出这个矩形
    painter.setPen(QColor(Qt::red));
    //设置画笔颜色为红色
    painter.drawText(ff,Qt::AlignHCenter,"yafeilinux");
    //我们这里先让字体水平居中
}

效果如下。


可以看到字符串是在最上面水平居中的。如果想让其在矩形正中间,我们可以使用Qt::AlignCenter。

这里我们也可以使用两个枚举变量进行按位与操作,例如可以使用Qt::AlignBottom|Qt::AlignHCenter实现让文字显示在矩形下面的正中间。效果如下。


对于较长的字符串,我们也可以利用“/n”进行换行,例如"yafei/nlinux"。效果如下。


3.如果要使文字更美观,我们就需要使用QFont类来改变字体。先在帮助中查看一下这个类。

可以看到它有好几个枚举变量来设置字体。下面的例子我们对主要的几个选项进行演示。

更改函数如下。

void Dialog::paintEvent(QPaintEvent *)
{
    QFont font("Arial",20,QFont::Bold,true);
    //设置字体的类型,大小,加粗,斜体
    font.setUnderline(true);
    //设置下划线
    font.setOverline(true);
    //设置上划线
    font.setCapitalization(QFont::SmallCaps);
    //设置大小写
    font.setLetterSpacing(QFont::AbsoluteSpacing,5);
    //设置间距
    QPainter painter(this);
    painter.setFont(font);
    //添加字体
    QRectF ff(100,100,300,200);
    painter.drawRect(ff);
    painter.setPen(QColor(Qt::red));
    painter.drawText(ff,Qt::AlignCenter,"yafeilinux");
}

效果如下。


这里的所有字体我们可以在设计器中进行查看。如下。

 

 

(4)原文教程十四 绘制路径

 

接着上一次的教程,这次我们学习在窗体上绘制路径。QPainterPath这个类很有用,这里我们只是说明它最常使用的功能,更深入的以后再讲。

1.我们更改paintEvent函数如下。

void Dialog::paintEvent(QPaintEvent *)
{
    
QPainterPath path;

    path.addEllipse(100,100,50,50);
    path.lineTo(200,200);

    QPainter painter(this);
    painter.setPen(Qt::green);
    painter.setBrush(Qt::yellow);

    painter.drawPath(path);
}

这里我们新建了一个painterPath对象,并加入了一个圆和一条线。然后绘制这个路径。

效果如下。


2.上面绘制圆和直线都有对应的函数啊,为什么还要加入一个painterPath呢?

我们再添加几行代码,你就会发现它的用途了。

void Dialog::paintEvent(QPaintEvent *)
{
    QPainterPath path;

    path.addEllipse(100,100,50,50);
    path.lineTo(200,200);

    QPainter painter(this);
    painter.setPen(Qt::green);
    painter.setBrush(Qt::yellow);

    painter.drawPath(path);

    QPainterPath path2;
    path2.addPath(path);
    path2.translate(100,0);

    painter.drawPath(path2);
}

效果如下。

这里我们又新建了一个painterPath对象path2,并将以前的path添加到它上面,然后我们更改了原点坐标为(100,0),这时你发现我们复制了以前的图形。这也就是painterPath类最主要的用途,它能保存你已经绘制好的图形。

3.这里我们应该注意的是绘制完一个图形后,当前的位置在哪里。

例如:

void Dialog::paintEvent(QPaintEvent *)
{
    QPainterPath path;

    path.lineTo(100,100);
    path.lineTo(200,100);

    QPainter painter(this);
    painter.drawPath(path);
}

效果如下。

可以看到默认是从原点(0,0)开始绘图的,当画完第一条直线后,当前点应该在(100,100)处,然后画第二条直线。

再如:

void Dialog::paintEvent(QPaintEvent *)
{
    QPainterPath path;

    path.addRect(50,50,40,40);
    path.lineTo(200,200);

    QPainter painter(this);

    painter.drawPath(path);
}

效果如下。可见画完矩形后,当前点在矩形的左上角顶点,然后从这里开始画直线。

我们可以自己改变当前点的位置。

void Dialog::paintEvent(QPaintEvent *)
{
    QPainterPath path;

    path.addRect(50,50,40,40);
    path.moveTo(100,100);
    path.lineTo(200,200);

    QPainter painter(this);
    painter.drawPath(path);
}

效果如下图。可见moveTo函数可以改变当前点的位置。

这里我们只讲解了绘制路径类最简单的应用,其实这个类很有用,利用它可以设计出很多特效。有兴趣的朋友可以查看一下它的帮助。因为我们这里只是简介,所以不再深入研究。

 

 

(5)原文教程十五  显示图片

 

现在我们来实现在窗口上显示图片,并学习怎样将图片进行平移,缩放,旋转和扭曲。这里我们是利用QPixmap类来实现图片显示的。

一、利用QPixmap显示图片。

1.将以前的工程文件夹进行复制备份,我们这里将工程文件夹改名为painter05。(以前已经说过,经常备份工程目录,是个很好的习惯)

2.在工程文件夹的debug文件夹中新建文件夹,我这里命名为images,用来存放要用的图片。我这里放了一张linux.jpg的图片。如下图所示。

3.在Qt Creator中打开工程。(即打开工程文件夹中的.pro文件),如图。

4.将dialog.cpp文件中的paintEvent()函数更改如下。

void Dialog::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QPixmap pix;
    pix.load("images/linux.jpg");
    painter.drawPixmap(0,0,100,100,pix);
}

这里新建QPixmap类对象,并为其添加图片,然后在以(0,0)点开始的宽和高都为100的矩形中显示该图片。你可以改变矩形的大小,看一下效果啊。最终程序运行效果如下。


(说明:下面的操作都会和坐标有关,这里请先进行操作,我们在下一节将会讲解坐标系统。)

二、利用更改坐标原点实现平移。

Qpainter类中的translate()函数实现坐标原点的改变,改变原点后,此点将会成为新的原点(0,0);

例如:

void Dialog::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QPixmap pix;
    pix.load("images/linux.jpg");
    painter.drawPixmap(0,0,100,100,pix);

    painter.translate(100,100); //将(100,100)设为坐标原点
    painter.drawPixmap(0,0,100,100,pix);
}

这里将(100,100)设置为了新的坐标原点,所以下面在(0,0)点贴图,就相当于在以前的(100,100)点贴图。效果如下。


三、实现图片的缩放。

我们可以使用QPixmap类中的scaled()函数来实现图片的放大和缩小。

例如:

void Dialog::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QPixmap pix;
    pix.load("images/linux.jpg");
    painter.drawPixmap(0,0,100,100,pix);

    qreal width = pix.width(); //获得以前图片的宽和高
    qreal height = pix.height();

    pix = pix.scaled(width*2,height*2,Qt::KeepAspectRatio);
    //将图片的宽和高都扩大两倍,并且在给定的矩形内保持宽高的比值
    painter.drawPixmap(100,100,pix);
}

其中参数Qt::KeepAspectRatio,是图片缩放的方式。我们可以查看其帮助。将鼠标指针放到该代码上,当出现F1提示时,按下F1键,这时就可以查看其帮助了。当然我们也可以直接在帮助里查找该代码。


这是个枚举变量,这里有三个值,只看其图片就可大致明白,Qt::IgnoreAspectRatio是不保持图片的长宽比,Qt::KeepAspectRatio是在给定的矩形中保持长宽比,最后一个也是保持长宽比,但可能超出给定的矩形。这里给定的矩形是由我们显示图片时给定的参数决定的,例如painter.drawPixmap(0,0,100,100,pix);就是在以(0,0)点为起始点的宽和高都是100的矩形中。

程序运行效果如下。


四、实现图片的旋转。

旋转使用的是QPainter类的rotate()函数,它默认是以原点为中心进行旋转的。我们要改变旋转的中心,可以使用前面讲到的translate()函数完成。

例如:

void Dialog::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QPixmap pix;
    pix.load("images/linux.jpg");
    painter.translate(50,50); //让图片的中心作为旋转的中心
    painter.rotate(90); //顺时针旋转90度
    painter.translate(-50,-50);
 //使原点复原
    painter.drawPixmap(0,0,100,100,pix);
}

这里必须先改变旋转中心,然后再旋转,然后再将原点复原,才能达到想要的效果。

运行程序,效果如下。


五、实现图片的扭曲。

实现图片的扭曲,是使用的QPainter类的shear(qreal sh,qreal sv)函数完成的。它有两个参数,前面的参数实现横行变形,后面的参数实现纵向变形。当它们的值为0时,表示不扭曲。

例如:

void Dialog::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QPixmap pix;
    pix.load("images/linux.jpg");
    painter.drawPixmap(0,0,100,100,pix);
    painter.shear(0.5,0); //横向扭曲
    painter.drawPixmap(100,0,100,100,pix);
}

效果如下:

其他扭曲效果:

painter.shear(0,0.5); //纵向扭曲                                               painter.shear(0.5,0.5); //横纵扭曲

                              

图片形状的变化,其实就是利用坐标系的变化来实现的。我们在下一节中将会讲解坐标系统。这一节中的几个函数,我们可以在其帮助文件中查看其详细解释。

 

 

 

声明:本文原创于yafeilinux的百度博客:http://hi.baidu.com/yafeilinux