QT简单绘图
2015-08-15 18:13
274 查看
一、画线
画笔样式
Qt::PenStyle
线帽样式
Qt::PenCapStyle
线连接样式
Qt::PenJoinStyle
练习1:线型
练习2:线帽类型
效果:
练习3:连接类型
练习4:画刷类型
效果:
二、绘图路径
绘图路径(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()函数加入到另一个绘图路径中。
例子:
三、反走样
由于采样不充分重建后造成的信息失真,叫做走样;用于减少或消除这种效果的技术称为反走样。
通过 enum QPainter::RenderHint 来设置绘图引擎的标志,QPainter::Antialiasing :指定反走样, QPainter::TextAntialiasing:指定文本反走样,QPainter::SmoothPixmapTransform指定光滑图片转换。
调用 QPainter::setRenderHint( QPainter::Antialiasing, true);可以将Antialiasing属性(反走样)设置为true。
四、渐变
Qt提供了三种渐变:线性渐变(QLinearGradient)、辐射渐变(QRadialGradient)和角度渐变(QConicalGradient)。
例子:
例子:
五、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()命令终止。
例如:
、绘制文字
画笔样式
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 );
、绘制文字
相关文章推荐
- Ubuntu安装Qt及QT Creator
- 【Qt OpenGL教程】27:阴影
- Ubuntu Qt5.5 Mysql driver
- 【Qt】]两种解决Qt5显示中文乱码的方法
- 如何将QVTKWidget添加到QtDesigner里
- Qt控件随窗口大小变化的设置方法(QTDesigner)
- QT 的信号与槽机制介绍
- 关于Qt中自定义槽和信号的简单示例
- MQTT broker and client
- Qt打包生成exe程序
- 关于Qt5 QML中Canvas画布叠加区域为透明时,如何传递鼠标事件到下层画布。
- QToolbutton实现图标和文字居中,qss
- 《转》PyQt4 精彩实例分析* 实例2 标准对话框的使用
- win32+QT 实现exe中执行返回的网页内容重定向到txt文件,根据需求读取里面内容
- 《转》QT界面怎么使控件随窗口大小变化一直居中显示
- QT5.3无法自动调用incomingConnection函数的问题
- QTP和Selenium对比
- ubuntu 14.04下Mysql的安装配置与QT的连接
- Qt容器
- 使用QT的qmake工具生成VS工程