QTransform世界变化

世界变化(QTransform )是在窗口-视口转换之外使用的变换矩阵。它允许移动、缩放、旋转或者拉伸绘制的项。

QTransform 比 QMatrix 先进,之前版本用 QMatrix。推荐使用  QTransform。

QTransform 与 QMatrix 不同之处在于,它是一个真正的 3x3 矩阵,允许视角转换,QTransform 的 toAffine() 方法允许将 QTransform 转换到QMatrix。如果视角转换已在矩阵指定,则转换将导致数据丢失。

一、平移

1. 设定左上角为原点坐标(0,0),在视口(200,200)的位置绘制一个边长为200的矩形。如下所示:

void QtWidgetTest::paintEvent(QPaintEvent *event)
{
	QPainter painter(this);
	painter.setPen(QPen(Qt::blue, 1, Qt::DashDotLine));
	painter.setBrush(Qt::red);
	QTransform transform;
//	transform.translate(100, 100); // 平移
//	painter.setTransform(transform);
	QPoint point = transform.map(QPoint(200, 200));
	qDebug() << "TEST --point = " << point;// 输出为(200,200)
	painter.drawRect(point.x(), point.y(), 200, 200);

	// 绘制网格线
	QPainter painter1(this);
	painter1.setPen(QPen(Qt::black, 1, Qt::DashLine));
	int nTemp = 200;
	QList<int> list{ 100, 200, 300, 400, 500 };
	foreach(int nTemp, list)
	{
		painter1.drawRect(0, 0, nTemp, nTemp);
		painter1.drawText(QPoint(nTemp + 10, 10), QString("%1").arg(nTemp));
		painter1.drawText(QPoint(10, nTemp + 10), QString("%1").arg(nTemp));
	}
	painter1.drawLine(0,0,1000,1000);
}

2. 使用世界坐标转换平移(100,100),将上面代码“transform.translate(100, 100); // 平移”注释去掉,如下所示:

void QtWidgetTest::paintEvent(QPaintEvent *event)
{
	...
	transform.translate(100, 100); // 平移
//	painter.setTransform(transform);
	QPoint point = transform.map(QPoint(200, 200));
	qDebug() << "TEST --point = " << point;// 输出为(300,300)
	painter.drawRect(point.x(), point.y(), 200, 200);
    ...
}

在(200,200)点输出的坐标,经过平移转换后,point位置为(300,300),输出结果如下:

3. 如果使用变化后QTransform 作为坐标系,将上面代码“painter.setTransform(transform);”注释去掉,如下所示:

void QtWidgetTest::paintEvent(QPaintEvent *event)
{
	...
	transform.translate(100, 100); // 平移
	painter.setTransform(transform);
	QPoint point = transform.map(QPoint(200, 200));
	qDebug() << "TEST --point = " << point;// 输出为(300,300)
	painter.drawRect(point.x(), point.y(), 200, 200);
    ...
}

在(200,200)点输出的坐标,经过平移转换后,point位置仍为(300,300),但绘制的结果相对坐标原定(100,100),绘出的位置为(400,400),这只是视口的显示结果。

、缩放

1. 设定左上角为原点坐标(0,0),在视口(200,200)的位置绘制一个边长为200的矩形。缩放比例为0.1倍,如下所示:

void QtWidgetTest::paintEvent(QPaintEvent *event)
{
	QPainter painter(this);
	painter.setPen(QPen(Qt::blue, 1, Qt::DashDotLine));
	painter.setBrush(Qt::red);
	QTransform transform;
	//transform.translate(100, 100);
	transform.scale(0.1, 0.1);
//	painter.setTransform(transform);
	QPoint point = transform.map(QPoint(200, 200));
	qDebug() << "TEST --point = " << point; // 输出(20,20)
	painter.drawRect(point.x(), point.y(), 200, 200);

	// 绘制网格线
	...
}

坐标点(200,200)经过缩放,输出的坐标为(20,20)。在输出位置绘制一个边长为200的矩形,如下图所示:

2. 如果使用变化后QTransform 作为坐标系,将上面代码“painter.setTransform(transform);”注释去掉,如下所示:

void QtWidgetTest::paintEvent(QPaintEvent *event)
{
	...
	QTransform transform;
	//transform.translate(100, 100);
	transform.scale(0.1, 0.1);
	painter.setTransform(transform);
	QPoint point = transform.map(QPoint(200, 200));
	qDebug() << "TEST --point = " << point; // 输出(20,20)
	painter.drawRect(point.x(), point.y(), 200, 200);

	// 绘制网格线
	...
}

point输出的坐标仍然是(20,20),以QTransform 作为坐标系,在视口进行显示时,按0.1的比例进行显示。转换后,矩形左上角位置应该为(2,2),边长为20。逻辑坐标的数据依然为左上角(20,20),边长为200。

、平移+缩放

 1. 在上面代码的基础上,增加代码transform.translate(100, 100);,如下所示:

void QtWidgetTest::paintEvent(QPaintEvent *event)
{
	...
	QTransform transform;
	transform.translate(100, 100);
	transform.scale(0.1, 0.1);
	painter.setTransform(transform);
	QPoint point = transform.map(QPoint(200, 200));
	qDebug() << "TEST --point = " << point; // 输出(20,20)
	painter.drawRect(point.x(), point.y(), 200, 200);

	// 绘制网格线
	...
}

按照上面的逻辑,QPoint(200, 200)转换为(120,120),不是(140,140),相当于在点(120,120)的位置绘制一个边长为200的矩形。

由于使用缩放和平移,以(120,120)缩放至(12,12),边长缩放至20,以平移的(100,100)为原点,所以输出位置为(112,112)。

 

 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值