Qt坐标转换

一、坐标系简 介。
Qt中每一个窗口都有一个坐标系,默认的,窗口左 上角为坐标原点,然后水平向右依次增大,水平向左依次减小,垂直向下依次增大,垂直向上依次减小。原点即为(0,0)点,然后以像素为单位增减。
例如:
void Dialog::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setBrush(Qt::red);
painter.drawRect(0,0,100,100);
painter.setBrush(Qt::yellow);
painter.drawRect(-50,-50,100,100);
}
我们先在原点(0,0)绘制了一个长宽都是100 像素的红色矩形,又在(-50,-50)点绘制了一个同样大小的黄色矩形。可以看到,我们只能看到黄色矩形的一部分。效果如下图。

二、坐标系变换。
坐标系变换是利用变换矩阵来进行的, 我们可以利用QTransform类来设置变换矩阵,因为一般我们不需要进行更改,所以这里不在涉及。下面我们只是对坐标系的平移,缩放,旋转,扭曲等应 用进行介绍。
1.利用 translate()函数进行平移变换。
void Dialog::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setBrush(Qt::yellow);
painter.drawRect(0,0,50,50);
painter.translate(100,100);//将点(100,100)设为原点
painter.setBrush(Qt::red);
painter.drawRect(0,0,50,50);
painter.translate(-100,-100);
painter.drawLine(0,0,20,20);
}
效果如下。

这里将 (100,100)点作为了原点,所以此时(100,100)就是(0,0)点,以前的(0,0)点就是
(-100,-100) 点。要想使原来的(0,0)点重新成为原点,就是将(-100,-100)设为原点。
2.利 用scale()函数进行比例变换,实现缩放效果。
void Dialog::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setBrush(Qt::yellow);
painter.drawRect(0,0,100,100);
painter.scale(2,2);//放大两倍
painter.setBrush(Qt::red);
painter.drawRect(50,50,50,50);
}
效果如下。

可以看 到,painter.scale(2,2),是将横纵坐标都扩大了两倍,现在的(50,50)点就相当于以前的
(100,100) 点。
3. 利用shear()函数就行扭曲变换。
void Dialog::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setBrush(Qt::yellow);
painter.drawRect(0,0,50,50);
painter.shear(0,1);//纵向扭曲 变形
painter.setBrush(Qt::red);
painter.drawRect(50,0,50,50);
}
效果如下。

这里,painter.shear(0,1),是对纵向进行扭曲,0表示不扭曲,当将第一个0更改时就会对横行进行扭曲,关于扭曲变换 到底是什么效果,你观察一下是很容易发现的。
4.利用rotate()函数进行比例变换,实现缩放效果。
void Dialog::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.drawLine(0,0,100,0);
painter.rotate(30);//以原点为中心,顺时针旋转30度
painter.drawLine(0,0,100,0);
painter.translate(100,100);
painter.rotate(30);
painter.drawLine(0,0,100,0);
}
效果如下。

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

效果如下。

这时就是我们想要的效果了。我们加的一句代码为painter.rotate(-30),这是因为前面已经将坐标旋转了30度,我们需 要将其再旋转回去,才能是以前正常的坐标系统。不光这个函数如此,这里介绍的这几个函数均如此,所以很容易出错。下面我们将利用两个函数来很好的解决这个 问题。
三、坐标系状态的保护。
我们可以先利用save()函数来保存坐标系现在的状态,然后进行变换操作,操作完之后,再用restore()函数将以前的坐标系状 态恢复,其实就是一个入栈和出栈的操作。
例如:
void Dialog::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.save();// 保存坐标系状态
painter.translate(100,100);
painter.drawLine(0,0,50,50);
painter.restore();//恢复以前的坐标系状态
painter.drawLine(0,0,50,50);
}
效果如下。


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


  • 3楼
  • 2013-06-20 11:06
Qt 坐标系统 笔记 zz http://cowboy.1988.blog.163.com/blog/static/7510579820115179312889/
World Corrdinates ==> Window Coordinates ==> Device Coordinates 
(逻辑坐标) 世界变换 中间态坐标 窗口视口变换 (物理坐标,设备坐标) 

在默认情况下,3个坐标系是一致的。世界变换
世界变换直接相关的函数:QPainter::setWorldMatrixEnabled 启用、禁用世界变换 
QPainter::setWorldTransform 设置世界变换 
QPainter::worldTransform 获取当前 
QPainter::resetTransform 重置为 QTransform() 

4个常用的函数

QPainter::scale
QPainter::shear
QPainter::rotate
QPainter::translate
注:它们通过直接调用的 QTransform 的相应成员直接修改世界变换void QPainter::scale(qreal sx, qreal sy)
{
...
d->state->worldMatrix.scale(sx,sy);
...
}
世界变换的两个马甲:

QPainter::setTransform
QPainter::transformvoid QPainter::setTransform(const QTransform &transform, bool combine )
{
setWorldTransform(transform, combine);
}
废弃的函数(从Qt4.3开始,QTransform 取代了QMatrix 的位置,下列函数已不建议使用):

QPainter::setWorldMatrix
QPainter::worldMatrix
...窗口视口变换
直接相关:QPainter::setViewTransformEnabled 启用、禁用 视口变换 
QPainter::viewTransformEnabled 

QPainter::setViewport 设置 视口(物理坐标) 
QPainter::setWindow 设置 窗口(与视口是同一矩形,中间态坐标) 

该变换是简单的线性变换。复合变换
窗口视口变换和世界变换的复合:

QPainter::combinedTransformQTransform QPainter::combinedTransform() const
{
Q_D(const QPainter);
return d->state->worldMatrix * d->viewTransform();
}
典型应用:对鼠标事件的响应中,将坐标从物理坐标变换成QPainter需要的逻辑坐标仿射变换、透射变换
Qt4.3(包括)之前的 QMatrix 只支持仿射变换(Affine transformation)。

平移(Translation)
缩放(Scale)
旋转(Rotation)
剪切(Shear)
QTransform 支持透射变换(perspective transformation)。m11 m12 m13 
m21 m22 m23 
m31 
dx m32 
dy m33 

变换关系:x' = m11*x + m21*y + dx
y' = m22*y + m12*x + dy
if (is not affine) {
w' = m13*x + m23*y + m33
x' /= w'
y' /= w'
}

相关(有待学习):
射影几何学、仿射几何学、欧氏几何学

  • 4楼
  • 2013-06-20 11:10
【转】Qt 坐标系统练习(三)


环境:PyQt4 或 PySide
目的:世界变换与窗口视口变换 练习
功能:在鼠标点击位置对应的物理坐标和逻辑坐标下分别绘制"十"字和文字说明截图
代码#--*-- coding:utf-8 --*--

import sys
try:
from PySide import QtCore, QtGui
except ImportError:
from PyQt4 import QtCore, QtGui

class Widget(QtGui.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.setMinimumSize(600,500)
self.transform = QtGui.QTransform()
self.viewport = QtCore.QRect()
self.window = QtCore.QRect()
self.poslist = []
self.setToolTip("click me")

def setTransform(self, trans):
self.transform = trans
self.update()

def setViewPort(self, rect):
self.viewport = rect
self.update()

def setWindow(self, rect):
self.window = rect
self.update()

def clear():
self.poslist = []
self.update()

def paintEvent(self, evt):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
for pos in self.poslist:
self.doPaint(painter, pos, "original")
if not self.viewport.isNull():
painter.setViewport(self.viewport)
if not self.window.isNull():
painter.setWindow(self.window)
painter.setTransform(self.transform)
trans = painter.combinedTransform().inverted()[0]
for pos in self.poslist:
self.doPaint(painter, trans.map(pos), "with transform")

def mousePressEvent(self, evt):
self.poslist.append(evt.pos())
self.update()
return super(Widget, self).mousePressEvent(evt)

def doPaint(self, painter, pos, flag):
x, y = pos.x(), pos.y()
painter.save()
painter.drawLine(QtCore.QLineF(x-10, y, x+10, y))
painter.drawLine(QtCore.QLineF(x, y-10, x, y+10))
painter.setPen(QtCore.Qt.blue);
painter.drawText(x, y, flag)
painter.restore()

class Dialog(QtGui.QDialog):
def __init__(self, parent=None):
super(Dialog, self).__init__(parent)

self.widget = Widget()

grid = QtGui.QGridLayout()
self.m11Edit = self.createEdit(-300, 300, 1, grid, 0, 0)
self.m12Edit = self.createEdit(-300, 300, 0, grid, 0, 1)
self.m13Edit = self.createEdit(-300, 300, 0, grid, 0, 2)
self.m21Edit = self.createEdit(-300, 300, 0, grid, 1, 0)
self.m22Edit = self.createEdit(-300, 300, 1, grid, 1, 1)
self.m23Edit = self.createEdit(-300, 300, 0, grid, 1, 2)
self.m31Edit = self.createEdit(-300, 300, 0, grid, 2, 0)
self.m32Edit = self.createEdit(-300, 300, 0, grid, 2, 1)
self.m33Edit = self.createEdit(-300, 300, 1, grid, 2, 2)
self.transformOkButton = QtGui.QPushButton("Use This Transform")
grid.addWidget(self.transformOkButton, 3, 0, 1, 3)

grid2 = QtGui.QGridLayout()
self.vxEdit = self.createEdit(-1, 800, 100, grid2, 0, 0, False)
self.vyEdit = self.createEdit(-1, 800, 100, grid2, 0, 1, False)
self.vwEdit = self.createEdit(-1, 800, 200, grid2, 0, 2, False)
self.vhEdit = self.createEdit(-1, 800, 200, grid2, 0, 3, False)
self.viewportOkButton = QtGui.QPushButton("Use This Viewport")
grid2.addWidget(self.viewportOkButton, 1, 0, 1, 4)

grid3 = QtGui.QGridLayout()
self.wxEdit = self.createEdit(-800, 800, -100, grid3, 0, 0, False)
self.wyEdit = self.createEdit(-800, 800, -100, grid3, 0, 1, False)
self.wwEdit = self.createEdit(-1, 800, 200, grid3, 0, 2, False)
self.whEdit = self.createEdit(-1, 800, 200, grid3, 0, 3, False)
self.windowOkButton = QtGui.QPushButton("Use This Window")
grid3.addWidget(self.windowOkButton, 1, 0, 1, 4)

vbox = QtGui.QVBoxLayout()
vbox.addLayout(grid)
vbox.addLayout(grid2)
vbox.addLayout(grid3)
vbox.addItem(QtGui.QSpacerItem(10,10, QtGui.QSizePolicy.Minimum, 
QtGui.QSizePolicy.Expanding))

hbox = QtGui.QHBoxLayout(self)
hbox.addWidget(self.widget)
hbox.addLayout(vbox)
self.setWindowTitle('Qt Coordinate System')

self.transformOkButton.clicked.connect(self.onTransformChanged)
self.viewportOkButton.clicked.connect(self.onViewportChanged)
self.windowOkButton.clicked.connect(self.onWindowChanged)

def createEdit(self, minimum, maximum, value, grid, i, j, d = True):
edit = QtGui.QDoubleSpinBox() if d else QtGui.QSpinBox()
edit.setRange(minimum, maximum)
edit.setValue(value)
edit.setButtonSymbols(QtGui.QAbstractSpinBox.NoButtons)
#edit.setMaximumWidth(50)
grid.addWidget(edit, i, j)
return edit

def onTransformChanged(self):
m11 = self.m11Edit.value()
m12 = self.m12Edit.value()
m13 = self.m13Edit.value()
m21 = self.m21Edit.value()
m22 = self.m22Edit.value()
m23 = self.m23Edit.value()
m31 = self.m31Edit.value()
m32 = self.m32Edit.value()
m33 = self.m33Edit.value()
self.widget.setTransform(QtGui.QTransform(m11, m12, m13, m21, m22, m23, m31, m32, m33))

def onViewportChanged(self):
x = self.vxEdit.value()
y = self.vyEdit.value()
w = self.vwEdit.value()
h = self.vhEdit.value()
self.widget.setViewPort(QtCore.QRect(x,y,w,h))

def onWindowChanged(self):
x = self.wxEdit.value()
y = self.wyEdit.value()
w = self.wwEdit.value()
h = self.whEdit.value()
self.widget.setWindow(QtCore.QRect(x,y,w,h))


if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
dlg = Dialog()
dlg.show()
sys.exit(app.exec_())

  • 5楼
  • 2013-06-20 12:03
【转】Qt 坐标系统练习(二) 

环境:PySide 或 PyQt4
主角:Qt 世界变换(world transform) 和 窗口视口变换(viewport window transform)
分别在以下条件下绘制同一图形: 

禁用两种变换
启用窗口视口变换
启用世界变换
启用两种变换截图代码#--*-- coding:utf-8 --*--
# (C) dbzhang800 2010

import sys
try:
from PySide import QtCore, QtGui
except ImportError:
from PyQt4 import QtCore, QtGui

class Widget(QtGui.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.setMinimumSize(600,500)

fontMetrics = QtGui.QFontMetrics(QtGui.QFont());
self.xBoundingRect = fontMetrics.boundingRect("x");
self.yBoundingRect = fontMetrics.boundingRect("y");
self.transform = QtGui.QTransform()
self.viewport = QtCore.QRect()
self.window = QtCore.QRect()

def setTransform(self, trans):
self.transform = trans
self.update()

def setViewPort(self, rect):
self.viewport = rect
self.update()

def setWindow(self, rect):
self.window = rect
self.update()

def paintEvent(self, evt):
painter = QtGui.QPainter(self)
self.doPaint(painter, "original")
if not self.viewport.isNull():
painter.setViewport(self.viewport)
if not self.window.isNull():
painter.setWindow(self.window)
self.doPaint(painter, "with view-window")
painter.setTransform(self.transform)
self.doPaint(painter, "with both")
painter.setViewTransformEnabled(False)
self.doPaint(painter, "with world transform")

def doPaint(self, p, flag):
p.save()
p.drawRect(0,0,40,40)
p.setPen(QtCore.Qt.blue);
p.drawText(20, 20, flag)

p.setPen(QtCore.Qt.red);
p.drawLine(0, 0, 40, 0);
p.drawLine(38, -2, 40, 0);
p.drawLine(38, 2, 40, 0);
p.drawText(50 - self.xBoundingRect.width() / 2,
0 + self.xBoundingRect.height() / 2, "x");

p.drawLine(0, 0, 0, 40);
p.drawLine(-2, 38, 0, 40);
p.drawLine(2, 38, 0, 40);
p.drawText(0 - self.yBoundingRect.width() / 2,
50 + self.yBoundingRect.height() / 2, "y");
p.restore()


class Dialog(QtGui.QDialog):
def __init__(self, parent=None):
super(Dialog, self).__init__(parent)

self.widget = Widget()

grid = QtGui.QGridLayout()
self.m11Edit = self.createEdit(-300, 300, 1, grid, 0, 0)
self.m12Edit = self.createEdit(-300, 300, 0, grid, 0, 1)
self.m13Edit = self.createEdit(-300, 300, 0, grid, 0, 2)
self.m21Edit = self.createEdit(-300, 300, 0, grid, 1, 0)
self.m22Edit = self.createEdit(-300, 300, 1, grid, 1, 1)
self.m23Edit = self.createEdit(-300, 300, 0, grid, 1, 2)
self.m31Edit = self.createEdit(-300, 300, 0, grid, 2, 0)
self.m32Edit = self.createEdit(-300, 300, 0, grid, 2, 1)
self.m33Edit = self.createEdit(-300, 300, 1, grid, 2, 2)
self.transformOkButton = QtGui.QPushButton("Use This Transform")
grid.addWidget(self.transformOkButton, 3, 0, 1, 3)

grid2 = QtGui.QGridLayout()
self.vxEdit = self.createEdit(-1, 800, 100, grid2, 0, 0, False)
self.vyEdit = self.createEdit(-1, 800, 100, grid2, 0, 1, False)
self.vwEdit = self.createEdit(-1, 800, 200, grid2, 0, 2, False)
self.vhEdit = self.createEdit(-1, 800, 200, grid2, 0, 3, False)
self.viewportOkButton = QtGui.QPushButton("Use This Viewport")
grid2.addWidget(self.viewportOkButton, 1, 0, 1, 4)

grid3 = QtGui.QGridLayout()
self.wxEdit = self.createEdit(-800, 800, -100, grid3, 0, 0, False)
self.wyEdit = self.createEdit(-800, 800, -100, grid3, 0, 1, False)
self.wwEdit = self.createEdit(-1, 800, 200, grid3, 0, 2, False)
self.whEdit = self.createEdit(-1, 800, 200, grid3, 0, 3, False)
self.windowOkButton = QtGui.QPushButton("Use This Window")
grid3.addWidget(self.windowOkButton, 1, 0, 1, 4)

vbox = QtGui.QVBoxLayout()
vbox.addLayout(grid)
vbox.addLayout(grid2)
vbox.addLayout(grid3)
vbox.addItem(QtGui.QSpacerItem(10,10, QtGui.QSizePolicy.Minimum, 
QtGui.QSizePolicy.Expanding))

hbox = QtGui.QHBoxLayout(self)
hbox.addWidget(self.widget)
hbox.addLayout(vbox)
self.setWindowTitle('Qt Coordinate System')

self.transformOkButton.clicked.connect(self.onTransformChanged)
self.viewportOkButton.clicked.connect(self.onViewportChanged)
self.windowOkButton.clicked.connect(self.onWindowChanged)

def createEdit(self, minimum, maximum, value, grid, i, j, d = True):
edit = QtGui.QDoubleSpinBox() if d else QtGui.QSpinBox()
edit.setRange(minimum, maximum)
edit.setValue(value)
edit.setButtonSymbols(QtGui.QAbstractSpinBox.NoButtons)
#edit.setMaximumWidth(50)
grid.addWidget(edit, i, j)
return edit

def onTransformChanged(self):
m11 = self.m11Edit.value()
m12 = self.m12Edit.value()
m13 = self.m13Edit.value()
m21 = self.m21Edit.value()
m22 = self.m22Edit.value()
m23 = self.m23Edit.value()
m31 = self.m31Edit.value()
m32 = self.m32Edit.value()
m33 = self.m33Edit.value()
self.widget.setTransform(QtGui.QTransform(m11, m12, m13, m21, m22, m23, m31, m32, m33))

def onViewportChanged(self):
x = self.vxEdit.value()
y = self.vyEdit.value()
w = self.vwEdit.value()
h = self.vhEdit.value()
self.widget.setViewPort(QtCore.QRect(x,y,w,h))

def onWindowChanged(self):
x = self.wxEdit.value()
y = self.wyEdit.value()
w = self.wwEdit.value()
h = self.whEdit.value()
self.widget.setWindow(QtCore.QRect(x,y,w,h))


if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
dlg = Dialog()
dlg.show()
sys.exit(app.exec_())

  • 6楼
  • 2013-06-20 12:05
从现在起,  你就是...火影 

  • 7楼
  • 2013-06-20 12:06

Qt4 Gossip: QMatrix
分类: QT图像加载及显示 2012-08-27 10:19 271人阅读 评论(0) 收藏 举报
qtmatrixsystemfloat图形api

转载自 http://hi.baidu.com/touchao/item/7a51b2e3d0e08710595dd845

QPainter默认的坐标系统是绘图装置的坐标系统,也就是左上角为原点,向右为正X,向下为正Y的坐标系统,坐标系统的转换常使用矩阵的方式来表现及进行运算,QMatrix的作用,正是让您可以利用其内建的矩阵,设定好相关的参数,然后让QPainter根据QMatrix的设定,来进行一些二维坐标系统的转换动作。

QMatrix的内部使用一个3x3的矩阵:

m11 m12 0 m21 m22 0 dx dy 1
dx与dy定义了水平与垂直移动,m11与m22定义了水平与垂直缩放(scaling),m12与m21定义了垂直与水平扭曲(shearing),想象您是坐在宇宙飞船中,在宇宙飞船从左上原点开到某个点之后,(x, y)是以您为中心所看到的坐标,但实际上宇宙飞船相对于左上角为原点的坐标为(x',y'),QMatrix的矩阵可以如以下的公式,将(x, y)转换为(x', y'):
x' = m11*x + m21*y + dx
y' = m22*y + m12*x + dy
当您使用QPainter要进行绘图时,可以您为中心所看到的坐标系统(x, y),使用QPainter的相关API来进行相关图形的绘制,这就像您在宇宙飞船中画图一样的方便,若有设定QMatrix,则会自动转换为计算机绘图时所看到的坐标系统(x', y'),如此就不用亲自进行一些复杂的转换动作,进行绘图时也较为直觉。

您可以藉由QMatrix的setMatrix()方法设定m11、m12、m21、m22、dx、dy,或者是直接使用translate()、rotate()、scale()与shear()等方法来直接进行移动、旋转、缩放、扭曲等坐标转换。

以下的范例为色彩轮的绘制,藉由设定HSV(Brightness,Hue,Saturation)中的「色相」来完成彩虹般的效果, HSV中的「色相」(Hue)是錂镜分光,主要有红、橙、黄、绿、蓝、紫...等八个主要色相。「亮度」(Brightness)是明暗表现,由白至黑的表现,在P.C.C.S(Practical Color Coordinate System)配色系统中,将之分为白、浅灰(浅,深)、浅中灰、中灰、暗中灰、暗灰(浅,深)、黑等。「彩度」(Saturation)也就是色彩的饱和程度,彩度最高的称之为「纯色」,最低为「无颜色」。
#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QMatrix>

class PainterWidget : public QWidget {
protected:
void paintEvent(QPaintEvent*);
};

void PainterWidget::paintEvent(QPaintEvent *event) {
QPainter painter(this);
QFont font("times", 18, QFont::Bold);
painter.setFont(font);
painter.setPen(Qt::black);

for (int i = 0; i < 36; i++) { // 进行 36 次旋转
QMatrix matrix;
matrix.translate(250, 250); // 移动中心至 (250, 250)
matrix.shear(0.0, 0.3); // 扭曲
matrix.rotate((float) i * 10); // 每次旋转 10 度
painter.setWorldMatrix(matrix); // 使用这个 QMatrix

QColor color;
color.setHsv(i * 10, 255, 255); // 设定彩虹效果
painter.setBrush(color); // 设定笔刷颜色
painter.drawRect(70, -10, 80, 10); // 画矩形

QString str;
str.sprintf("H=%d", i*10);
painter.drawText(80 + 70 + 5, 0, str); // 绘制角度文字
}
}

int main(int argc, char *argv[]) {
QApplication app(argc, argv);

PainterWidget pWidget;
pWidget.setWindowTitle("QMatrix");
pWidget.resize(500, 500);
pWidget.show();

return app.exec();
}

转载于:https://www.cnblogs.com/duguochao/p/4375893.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本资源为Qt绘图基础,世界坐标转换为逻辑坐标世界坐标原点在视图左上角,本例子通过世界坐标转换,将坐标原点定位在视图中央,Y轴向上,X轴向右,并绘制坐标轴,基于逻辑坐标下的绘图,可将转换函数取消生效,对比世界坐标下的绘图。 重写PainterEvent函数: void QtPixPainter::paintEvent(QPaintEvent* event) { QPainter painter(this); // 反走样 painter.setRenderHint(QPainter::Antialiasing, true); //物理坐标与逻辑坐标转换,如果不转换,下面的绘图都是在世界坐标下 setWorldTransform(painter); // 其他一些绘制矩形,多边形的例子,经过上面转换,都是在逻辑坐标下 drawRectScale(painter); //draw_shearRect(painter); //利用rotate()函数进行比例变换,实现缩放效果 //draw_rotate_act(painter); //draw_by_save_restore(painter); //transform_draw_SinX(painter); transform_draw(painter); local_drawConvexPolygon(painter); } // 将世界坐标(原点左上角)转换为逻辑坐标(原点在屏幕中间) QPointF QtPixPainter::mapToScene(const QPointF& point) { QTransform transMatrix = _transform.inverted(); //翻转矩阵? return transMatrix.map(point); //将点piont映射到transMatrix定义的坐标中来 } // 将鼠标的逻辑位置返回并以标签形式展示 void QtPixPainter::mouseMoveEvent(QMouseEvent* event) { QString msg; QPointF mouse_po = mapToScene(event->pos()); //总是返回屏幕物理坐标 double x = mouse_po.x(); // 总是返回屏幕物理坐标 double y = mouse_po.y(); QString str = "(" + QString::number(x) + "," + QString::number(y) + ")"; //qDebug()<<"world x = "<pos().x()<<",world y = "<pos().y(); m_mouse_lable->setText(str); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值