QT简单绘图

一、画线

画笔样式

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 );

 

 

 

 

 

 

 

、绘制文字


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值