Qt坐标绘图

来源:互联网 发布:域名批量注册查询 编辑:程序博客网 时间:2024/05/13 00:24

转载地址:http://blog.csdn.net/sunboy_2050/article/details/6573849

 

1907人阅读评论(0)收藏举报

1.    坐标系简介

Qt中每一个窗口都有自己的一个坐标系,默认窗口左上角为坐标原点(0,0),然后水平向右依次增大(X轴),垂直向下依次增大(Y轴)。例如:

void  MyDraw::paintEvent( QPaintEvent * )

{

         QPainterpaint( this );

         paint.setBrush(Qt::green );

         paint.drawRect(0, 0, 100, 100 );

         paint.setBrush(Qt::red );

         paint.drawRect(-50, -50, 100, 100 );

}

上例中,先在原点(0,0)绘制了一个长、宽都是100像素的绿色矩形,然后在点(-50,-50)绘制了一个同样大小(长、宽均为100像素)的红色矩形,只能看到红色矩形的一部分。

效果图如下:

这是因为在点(-50,-50)绘制的长、宽各100图形的其它3/4均被窗体遮挡了。

2.    坐标系变换。

坐标系变换是利用变换矩阵来进行的,我们可以利用QTransform类来设置变换矩阵,因为一般我们不需要进行更改,所以这里不在涉及。下面我们只是对坐标系的平移,缩放,旋转,扭曲等应用进行介绍。

2.1 利用translate()函数进行平移变换。

void  MyDraw::paintEvent( QPaintEvent * )

{

         QPainterpaint( this );

         paint.setBrush(Qt::green );

         paint.drawRect(0, 0, 100, 100 );

        paint.translate(100, 100 );    // 坐标变换,重新把点(100,100)作为原点

         paint.setBrush(Qt::red );

         paint.drawRect(0, 0, 100, 100 );

         paint.translate(-100, -100 );  // 坐标变换,移动(-100,-100)恢复至原点(0,0)

         paint.drawLine(0, 0, 50, 50 );

}

效果图如下:

这里将(100,100)点作为了原点,所以此时(100,100)就是(0,0)点,以前的(0,0)点就是(-100,-100)点。要想使原来的(0,0)点重新成为原点,就是将(-100,-100)设为原点。

2.2利用scale()函数进行比例变换,实现缩放效果。

void  MyDraw::paintEvent( QPaintEvent * )

{

         QPainterpaint( this );

         paint.setBrush(Qt::green );

         paint.drawRect(0, 0, 100, 100 );

        paint.scale( 2, 2);            //paint放大两倍

         paint.setBrush(Qt::red );

         paint.drawRect(50, 50, 50, 50 );

         paint.scale( 0.5,0.5 );     // paint缩小一半(恢复原来)

         paint.setBrush(Qt::yellow );

         paint.drawEllipse(0, 0, 100, 100 );

}

效果图如下:

可以看到,painter.scale(2,2),是将横纵坐标都扩大了两倍,现在的(50,50)点就相当于以前的(100,100)点。

2.3利用shear()函数就行扭曲变换。

void  MyDraw::paintEvent( QPaintEvent * )

{

         QPainterpaint( this );

         paint.setBrush(Qt::green );

         paint.drawRect(0, 0, 100, 100 );

         paint.shear( 0, 1 );             // 纵向扭曲1倍

         paint.setBrush(Qt::red );

         paint.drawRect(0, 100, 100, 100 );

         paint.shear( 0, -1);            // 恢复原状

         paint.setBrush(Qt::yellow );

         paint.drawEllipse(0, 0, 100, 100 );

}

效果图如下:

这里,painter.shear(0,1),是对纵向进行扭曲,0表示不扭曲,当将第一个0更改时就会对横行进行扭曲,关于扭曲变换到底是什么效果,你观察一下是很容易发现的。

2.4利用rotate()函数进行比例变换,实现缩放效果。

void  MyDraw::paintEvent( QPaintEvent * )

{

         QPainterpaint( this );

         paint.drawLine(0, 0, 100, 0 );

         paint.rotate( 30);                              // 顺时针旋转30度

         paint.drawLine(0, 0, 100, 0 );

         paint.translate(100, 100 );              // 坐标变换, 原点(0,0)移至(100,100)点

         paint.drawLine(0, 0, 100, 0 );

         paint.rotate( 30);                              // 顺时针旋转30度

         paint.drawLine(0, 0, 100, 0 );

}

效果图如下:

因为默认的rotate()函数是以原点为中心进行顺时针旋转的,所以我们要想使其以其他点为中心进行旋转,就要先进行原点的变换。这里的painter.translate(100,100)将(100,100)设置为新的原点,想让直线以其为中心进行旋转,可是你已经发现效果并非如此。是什么原因呢?我们添加一条语句,如下:

void  MyDraw::paintEvent( QPaintEvent * )

{

         QPainterpaint( this );

         paint.drawLine(0, 0, 100, 0 );

        paint.rotate(30 );                               // 顺时针旋转30度

         paint.drawLine(0, 0, 100, 0 );

         paint.rotate( -30 );

         paint.translate(100, 100 );               // 坐标变换, 原点(0,0)移至(100,100)点

         paint.drawLine(0, 0, 100, 0 );

        paint.rotate(30 );                               // 顺时针旋转30度

         paint.drawLine(0, 0, 100, 0 );

}

效果图如下:


这时就是我们想要的效果了。我们加的一句代码为painter.rotate(-30),这是因为前面已经将坐标旋转了30度,我们需要将其再旋转回去,才能是以前正常的坐标系统。不光这个函数如此,这里介绍的这几个函数均如此,所以很容易出错。下面我们将利用两个函数来很好的解决这个问题。

3.    坐标系状态的保护。

我们可以先利用save()函数来保存坐标系现在的状态,然后进行变换操作,操作完之后,再用restore()函数将以前的坐标系状态恢复,其实就是一个入栈和出栈的操作。

例如:

void MyDraw::paintEvent( QPaintEvent * )

{

         QPainterpaint( this );

         paint.save();            // 保存坐标状态

         paint.translate(100, 100 );

         paint.setBrush(Qt::green );

         paint.drawRect(0, 0, 100, 100 );

         paint.drawLine(0, 0, 50, 50 );

         paint.restore();        // 恢复坐标状态

         paint.setBrush(Qt::red );

         paint.drawRect(0, 0, 100, 100 );

         paint.drawLine(0, 0, 50, 50 );

}

效果图如下:

利用好这两个函数,可以实现快速的坐标系切换,绘制出不同的图形。

源代码如下:

[cpp] view plaincopyprint?
  1. /*******************************************************
  2. * Qt coordinates and Painter
  3. *
  4. * Version: Qt 3.1.2
  5. * Author : yanggang2050@gmail.com
  6. * Date   : 2011.06.28 23:08:12
  7. *
  8. *******************************************************/ 
  9.  
  10. #include <qapplication.h> 
  11. #include <qwidget.h> 
  12.  
  13. #include <qpainter.h> 
  14. #include <qmessagebox.h> 
  15.  
  16. class MyDraw : public QWidget 
  17.  
  18. public
  19.     void paintEvent( QPaintEvent * );      // 绘制图形 
  20.     void mousePressEvent( QMouseEvent * ); // 获取鼠标位置 
  21. }; 
  22.  
  23. /////////////////////////////////////////////// 
  24. //   绘制图形(以下paintEvent一次使用一个)   /// 
  25. /////////////////////////////////////////////// 
  26.  
  27. /******* 1 paint *******/ 
  28. void MyDraw::paintEvent( QPaintEvent * ) 
  29.     QPainter paint( this ); 
  30.  
  31.     paint.setBrush( Qt::green ); 
  32.     paint.drawRect( 0, 0, 100, 100 ); 
  33.     paint.setBrush( Qt::red ); 
  34.     paint.drawRect( -50, -50, 100, 100 ); 
  35.  
  36. /******* 2.1 translate *******/ 
  37. void MyDraw::paintEvent( QPaintEvent * ) 
  38.     QPainter paint( this ); 
  39.  
  40.     paint.setBrush( Qt::green ); 
  41.     paint.drawRect( 0, 0, 100, 100 ); 
  42.  
  43.     paint.translate( 100, 100 );    // 坐标变换,重新把点(100,100)作为原点 
  44.  
  45.     paint.setBrush( Qt::red ); 
  46.     paint.drawRect( 0, 0, 100, 100 ); 
  47.  
  48.     paint.translate( -100, -100 );  // 坐标变换,移动(-100,-100)恢复至原点(0,0) 
  49.  
  50.     paint.drawLine( 0, 0, 50, 50 ); 
  51.  
  52.  
  53. /******* 2.2 scale *******/ 
  54. void MyDraw::paintEvent( QPaintEvent * ) 
  55.     QPainter paint( this ); 
  56.  
  57.     paint.setBrush( Qt::green ); 
  58.     paint.drawRect( 0, 0, 100, 100 ); 
  59.  
  60.     paint.scale( 2, 2 );        // paint放大两倍 
  61.  
  62.     paint.setBrush( Qt::red ); 
  63.     paint.drawRect( 50, 50, 50, 50 ); 
  64.  
  65.     paint.scale( 0.5, 0.5 );    // paint缩小一半(恢复原来) 
  66.  
  67.     paint.setBrush( Qt::yellow ); 
  68.     paint.drawEllipse( 0, 0, 100, 100 ); 
  69.  
  70. /******* 2.3 shear *******/ 
  71. void MyDraw::paintEvent( QPaintEvent * ) 
  72.     QPainter paint( this ); 
  73.  
  74.     paint.setBrush( Qt::green ); 
  75.     paint.drawRect( 0, 0, 100, 100 ); 
  76.  
  77.     paint.shear( 0, 1 );    // 纵向扭曲1倍 
  78.  
  79.     paint.setBrush( Qt::red ); 
  80.     paint.drawRect( 0, 100, 100, 100 ); 
  81.  
  82.     paint.shear( 0, -1 );   // 恢复原状 
  83.  
  84.     paint.setBrush( Qt::yellow ); 
  85.     paint.drawEllipse( 0, 0, 100, 100 ); 
  86.  
  87. /******* 2.4 rotate *******/ 
  88. void MyDraw::paintEvent( QPaintEvent * ) 
  89.     QPainter paint( this ); 
  90.  
  91.     paint.drawLine( 0, 0, 100, 0 ); 
  92.  
  93.     paint.rotate( 30 );             // 顺时针旋转30度 
  94.     paint.drawLine( 0, 0, 100, 0 ); 
  95.  
  96.     paint.translate( 100, 100 );    // 坐标变换, 原点(0,0)移至(100,100)点 
  97.     paint.drawLine( 0, 0, 100, 0 ); 
  98.  
  99.     paint.rotate( 30 );             // 顺时针旋转30度 
  100.     paint.drawLine( 0, 0, 100, 0 ); 
  101.  
  102. /******* 2.4-2 rotate *******/ 
  103. void MyDraw::paintEvent( QPaintEvent * ) 
  104.     QPainter paint( this ); 
  105.  
  106.     paint.drawLine( 0, 0, 100, 0 ); 
  107.  
  108.     paint.rotate( 30 );             // 顺时针旋转30度 
  109.     paint.drawLine( 0, 0, 100, 0 ); 
  110.  
  111.     paint.rotate( -30 ); 
  112.     paint.translate( 100, 100 );    // 坐标变换, 原点(0,0)移至(100,100)点 
  113.     paint.drawLine( 0, 0, 100, 0 ); 
  114.  
  115.     paint.rotate( 30 );             // 顺时针旋转30度 
  116.     paint.drawLine( 0, 0, 100, 0 ); 
  117.  
  118.  
  119. /******* 3 save - restore *******/ 
  120. void MyDraw::paintEvent( QPaintEvent * ) 
  121.     QPainter paint( this ); 
  122.  
  123.     paint.save();       // 保存坐标状态 
  124.     paint.translate( 100, 100 ); 
  125.     paint.setBrush( Qt::green ); 
  126.     paint.drawRect( 0, 0, 100, 100 ); 
  127.     paint.drawLine( 0, 0, 50, 50 ); 
  128.  
  129.     paint.restore();    // 恢复坐标状态 
  130.     paint.setBrush( Qt::red ); 
  131.     paint.drawRect( 0, 0, 100, 100 ); 
  132.     paint.drawLine( 0, 0, 50, 50 ); 
  133.  
  134.  
  135.  
  136. // 获取鼠标位置 
  137. void MyDraw::mousePressEvent( QMouseEvent * e) 
  138.     QString mousePos = "X = " + QString::number( e->pos().x() ) +" "  
  139.                    + "Y = " + QString::number( e->pos().y() ); 
  140.  
  141.     QMessageBox::information( this, tr("获取鼠标点击位置"), mousePos ); 
  142.  
  143. // 主函数 
  144. int main(int argc,char **argv) 
  145.     QApplication app(argc, argv); 
  146.  
  147.     MyDraw draw; 
  148.     app.setMainWidget( &draw ); 
  149.     draw.show(); 
  150.  
  151.     return app.exec(); 

 

原创粉丝点击