您的位置:首页 > 编程语言 > Qt开发

QT简单绘图

2015-08-15 18:13 274 查看
一、画线

画笔样式

Qt::PenStyle

enum PenStyle { // pen style
NoPen,
SolidLine,
DashLine,
DotLine,
DashDotLine,
DashDotDotLine,
CustomDashLine
#ifndef Q_MOC_RUN
, MPenStyle = 0x0f
#endif
};


线帽样式

Qt::PenCapStyle

enum PenCapStyle { // line endcap style
FlatCap = 0x00,
SquareCap = 0x10,
RoundCap = 0x20,
MPenCapStyle = 0x30
};


线连接样式

Qt::PenJoinStyle

enum PenJoinStyle { // line join style
MiterJoin = 0x00,
BevelJoin = 0x40,
RoundJoin = 0x80,
SvgMiterJoin = 0x100,
MPenJoinStyle = 0x1c0
};


练习1:线型

painter.setPen( Qt::SolidLine);
painter.drawLine( 10,10, 400, 10);

painter.setPen( Qt::DashLine);
painter.drawLine( 10, 20, 400, 20);

painter.setPen( Qt::DotLine );
painter.drawLine(10, 30, 400, 30);

painter.setPen(Qt::DashDotLine);
painter.drawLine(10, 40, 400, 40);

painter.setPen(Qt::DashDotDotLine);
painter.drawLine(10, 50, 400, 50);

QPen CustomPen;
QVector<qreal> vect;
vect.push_back( 10.0);//第一个划线的长度
vect << 5.0;//第一个空的长度
vect << 20.0;//第二个划线的长度
vect << 10.0;//第二个空的长度
//可以继续交替设置划线、空的长度
CustomPen.setDashPattern( vect);
painter.setPen( CustomPen );
painter.drawLine(10, 60, 400, 60);
效果:



练习2:线帽类型

QPen pen1;
pen1.setWidth(10);

pen1.setCapStyle( Qt::FlatCap);
painter.setPen( pen1 );
painter.drawLine( 10, 80, 400, 80);

pen1.setCapStyle( Qt::SquareCap );
painter.setPen(pen1);
painter.drawLine(10, 100, 400, 100);

pen1.setCapStyle(Qt::RoundCap);
painter.setPen(pen1);
painter.drawLine(10, 120, 400, 120);

pen1.setCapStyle(Qt::MPenCapStyle);
painter.setPen(pen1);
painter.drawLine(10, 140, 400, 140);


效果:



练习3:连接类型

QPen pen2;
pen2.setWidth(10);

pen2.setJoinStyle( Qt::RoundJoin);
painter.setPen(pen2);
QVector<QPoint> Pt_vec;
Pt_vec << QPoint(10, 200) << QPoint(100, 50) << QPoint(200, 200);
painter.drawPolyline( Pt_vec);

pen2.setJoinStyle(Qt::MiterJoin);
painter.setPen(pen2);
Pt_vec.clear();
Pt_vec << QPoint(10, 240) << QPoint(100, 90) << QPoint(200, 240);
painter.drawPolyline(Pt_vec);

pen2.setJoinStyle(Qt::BevelJoin);
painter.setPen(pen2);
Pt_vec.clear();
Pt_vec << QPoint(10, 280) << QPoint(100, 130) << QPoint(200, 280);
painter.drawPolyline(Pt_vec);

pen2.setJoinStyle(Qt::SvgMiterJoin);
painter.setPen(pen2);
Pt_vec.clear();
Pt_vec << QPoint(10, 320) << QPoint(100, 170) << QPoint(200, 320);
painter.drawPolyline(Pt_vec);
效果:



练习4:画刷类型

QPen pen3;
pen3.setWidth( 10 );

pen3.setBrush( Qt::green);
painter.setPen( pen3 );
painter.drawLine( 10, 340, 400, 340);

pen3.setBrush( QBrush( Qt::CrossPattern) );
painter.setPen( pen3 );
painter.drawLine(10, 360, 400, 360);

pen3.setBrush(QBrush(Qt::Dense5Pattern));
painter.setPen(pen3);
painter.drawLine(10, 380, 400, 380);

pen3.setBrush(QBrush(Qt::BDiagPattern));
painter.setPen(pen3);
painter.drawLine(10, 400, 400, 400);

QLinearGradient linearGradient(10,0, 400, 0);
linearGradient.setColorAt( 0, Qt::red);
linearGradient.setColorAt( 1, Qt::green);
pen3.setBrush(  linearGradient );
painter.setPen(pen3);
painter.drawLine(10, 420, 400, 420);

QRadialGradient radialGradient(10,440, 400);
radialGradient.setColorAt(0,Qt::red);
radialGradient.setColorAt(0.2,Qt::blue);
radialGradient.setColorAt(0.5,Qt::green);
radialGradient.setColorAt(0.7,Qt::yellow);
radialGradient.setColorAt(1.0,Qt::gray);
pen3.setBrush( radialGradient );
painter.setPen( pen3);
painter.drawLine(10, 440, 400, 440);

QImage image("winblender.ico");
QBrush brush(image);
pen3.setBrush( brush);
painter.setPen(pen3);
painter.drawLine(10, 460, 400, 460);


效果:



二、绘图路径

绘图路径(painter path)由基本图元(矩形,椭圆,直线,曲线)组成,绘图路径可以是闭合的路径,如矩形和圆,或者是非闭合的路径,如直线和曲线。

绘图路径在Qt中使用QPainterPth类表示,它提供了绘图操作的容器,可以使图形能够复用。绘图路径可以进行填充,显示轮廓和裁剪。要生成可填充的轮廓的绘图路径,可以使用QPainterPathStroker类.

使用QPainterPath的优点是复杂的图形只需创建一次,就可以多次使用,调用QPainter::drawPath()可以多次绘制。QPainterPath对象可以时只有起点的空路径,或者从其他QPainterPath对象复制,创建了QPainterPath对象后,可以使用lineTo(),cubicTo(),quadTo() 函数将直线和曲线添加到路径中来,直线和曲线从currentPosition()开始绘制。currentPosition()总是返回最后的子路经绘制的终点。使用moveTo()函数可以在不增加路径的情况下移动currentPositon(),它关闭了一个子路经,开始一个新的子路经。closeSubPath()也可以关闭当前路径,并从currentPosition()连接一条直线到绘图路径的起点。

QPainter可以使用addEllipse(),addPath(),addRect(),addRegion(),addText()将Qt的一些基本图元加入绘图路径。一个已有的绘图路径可以通过connectPath()函数加入到另一个绘图路径中。

例子:

QPainterPath path;
path.addRect(0, 0, 100, 100);
path.addEllipse( 100, 100, 50,50);

painter.setPen( Qt::yellow );
painter.setBrush( Qt::green );
painter.drawPath( path );

path.translate( 200, 0);
painter.drawPath( path );

path.translate( 200, 0);
painter.drawPath( path );
效果:



三、反走样

由于采样不充分重建后造成的信息失真,叫做走样;用于减少或消除这种效果的技术称为反走样。

通过 enum QPainter::RenderHint 来设置绘图引擎的标志,QPainter::Antialiasing :指定反走样, QPainter::TextAntialiasing:指定文本反走样,QPainter::SmoothPixmapTransform指定光滑图片转换。

调用 QPainter::setRenderHint( QPainter::Antialiasing, true);可以将Antialiasing属性(反走样)设置为true。

四、渐变

Qt提供了三种渐变:线性渐变(QLinearGradient)、辐射渐变(QRadialGradient)和角度渐变(QConicalGradient)。

例子:

painter.setRenderHint( QPainter::Antialiasing, true );
QLinearGradient linearGradient( 60, 50, 200, 200);
linearGradient.setColorAt( 0.2, Qt::white );
linearGradient.setColorAt( 0.6, Qt::green );
linearGradient.setColorAt( 1.0, Qt::black );

painter.setBrush( QBrush(linearGradient ));
painter.drawEllipse( 50, 50, 200, 200);
效果:



例子:

//1.角度渐变
const int r = 150;
QConicalGradient conicalGradient( 0, 0, 0);

conicalGradient.setColorAt( 0.0, Qt::red );
conicalGradient.setColorAt( 60.0/360.0, Qt::yellow );
conicalGradient.setColorAt( 120.0/360.0, Qt::green );
conicalGradient.setColorAt( 180.0/360.0, Qt::cyan );
conicalGradient.setColorAt( 240.0/360.0, Qt::blue );
conicalGradient.setColorAt( 300.0/360.0, Qt::magenta );
conicalGradient.setColorAt( 1.0, Qt::red);

painter.translate( r, r); //将坐标系的原点设置到(r, r)点处

QBrush brush( conicalGradient );
painter.setPen( Qt::NoPen );
painter.setBrush( brush );
painter.drawEllipse( QPoint(0, 0), r, r);

painter.translate( -1*r, -1*r);//将坐标系的原点设置回窗口左上角

//2.辐射渐变
QRadialGradient radialGradient( QPoint(400, 400), 200, QPoint(200, 400) );
radialGradient.setColorAt(0, Qt::red );
radialGradient.setColorAt( 0.5, Qt::green );
radialGradient.setColorAt(1.0, Qt::blue );

QBrush brush1( radialGradient );
painter.setBrush( brush1 );
painter.drawEllipse( QPoint(400, 400), 200, 200);
效果:



五、QPainter状态的保存和恢复

QPainter提供了内置的函数:save()和restore();save()就是保存当前状态,比如画笔颜色、粗细等,restore()则恢复上一次保存的结果,这连个函数必须成对出现。功能以及实现方法类似于OpenGL中的glPushAttrib()和glPopAttrib()函数。

六、Qt坐标系统

1、Qt坐标变换

Qt提供四种坐标变换:平移translate, 旋转rotate, 缩放scale 和扭曲shear,这些变换是针对坐标系的。

2、逻辑坐标、物理坐标

window代表窗口坐标、viewport代表物理坐标;

注意:

resize函数设置的是窗口的像素大小,比如resize(400, 400 );设置一个400px*400px的窗口,如果你的屏幕分辨率是1024*768,那么该窗口大小大概占你屏幕长的0.4 倍。

setWindow设置的是窗口坐标,比如对上述400px*400px的窗口,如果setWindow(0,0, 200, 200),那么逻辑坐标(200, 200),对应窗口的右下角。即一个像素长度等于1/2个逻辑单位。

setViewport设置的是物理坐标,对于400px*400px的窗口,如果setViewport(0,0,200, 200),就是将物理的200px*200px映射到窗口的长宽400px*400px;注意这里是物理坐标和窗口的实际像素大小之间的对应关系,与窗口逻辑坐标无关,如果窗口逻辑坐标范围为(0,400),那么世界坐标(逻辑坐标)到窗口坐标系统的转换比例为1:1,即逻辑点(400,400),对应窗口坐标系(400,400);窗口坐标系统到物理坐标系统的比例为2:1,所以对应的物理坐标点为(200,200),该点在窗口的中央。

逻辑坐标、窗口坐标与物理坐标之间的关系:



传给QPainter的是逻辑坐标(也称为世界坐标),逻辑坐标可以通过变换矩阵转换为窗口坐标,窗口坐标通过window-viewport转换为物理坐标(也就是设备坐标)。

七、绘制图像

绘图设备是继承QPainterDevice的类,使用QPainter可以在任何QPaintDevice的子类上进行绘制。QPixmap、QBitmap、QImage、QPicture都是绘图设备。

1、QPixmap

QPixmap继承了QPaintDevice,是针对屏幕进行特殊优化的,因此,它与实际的底层显示设备息息相关(不同的操作系统平台下,QPixmap的显示可能会有所差别);在程序中打开图片文件可以使用QPixmap,使用QPainter::drawPixmap()函数可以把图片文件绘制到一个QLabel、QPushButton或其他设备上。

QPixmap提供“隐式数据共享”,可以直接传值,不需要传指针。

2、QBitmap继承自QPixmap,因此具有QPixmap的所有特性,不同之处是QBitmap的色深始终为1,只有黑白两色的图像数据(其他颜色使用点的疏密程度来体现)。

由于QBitmap色深小,因此只占用很少的存储空间,所以适合做光标文件和笔刷。

3、QImage

QImage使用独立于硬件的绘图系统,因此提供了像素级别的操作,并且能够在不同的系统之上提供一个一致的显示形式。QImage与QPixmap相比,最大的优势在于能够进行像素级别的操作。

4、QPicture

QPicture是平台无关的,因此它可以使用在多种设备之上,比如svg、pdf、ps、打印机或者屏幕。

如果要记录下QPainter的命令,可以使用QPainter::begin()函数,将QPicture实例作为参数传递进去,以便告诉系统开始记录,记录完毕后使用QPainter::end()命令终止。

例如:

QPicture picture;

painter.begin( &picture );              //在picture进行绘制
painter.drawEllipse( 10, 20, 80, 70 );  //绘制一个椭圆
painter.end();                          //绘制完成

picture.save("drawing.pic")             //保存picture
要重现命令,使用QPicture::load()函数进行装载:

picture.load("drawing.pic");              //加载picture

painter.begin( &myImage );                //在myImage进行绘制
painter.drawPicture( 0, 0, picture);      //在(0,0)点开始绘制picture
painter.end();                            //绘制完成
picture.play( &painter );


、绘制文字
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: