精华内容
下载资源
问答
  • Qt坐标转换

    2015-03-29 16:55:00
    Qt中每一个窗口都有一个坐标系,默认的,窗口左 上角为坐标原点,然后水平向右依次增大,水平向左依次减小,垂直向下依次增大,垂直向上依次减小。原点即为(0,0)点,然后以像素为单位增减。例如:void Dialog::...
    一、坐标系简 介。
    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);
    }
    效果如下。


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


    Qt 坐标系统 笔记 zzhttp://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
    从现在起, 你就是...火影 

    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

    展开全文
  • QT 坐标转换 实现图片旋转

    千次阅读 2011-05-31 17:26:00
    QT 坐标转换 实现图片旋转

    QT 坐标转换 实现图片旋转等

     (2010-06-07 15:07:40)
    by 李冬冬

    一、利用QPixmap显示图片。

    1.将以前的工程文件夹进行复制备份,我们这里将工程文件夹改名为painter05。(以前已经说过,经常备份工程目录,是个很好的习惯)

    2.在工程文件夹的debug文件夹中新建文件夹,我这里命名为images,用来存放要用的图片。我这里放了一张linux.jpg的图片。如下图所示。

    3.在Qt Creator中打开工程。(即打开工程文件夹中的.pro文件),如图。

    4.将dialog.cpp文件中的paintEvent()函数更改如下。

    void Dialog::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        QPixmap pix;
        pix.load(“images/linux.jpg”);
        painter.drawPixmap(0,0,100,100,pix);
    }

    这里新建QPixmap类对象,并为其添加图片,然后在以(0,0)点开始的宽和高都为100的矩形中显示该图片。你可以改变矩形的大小,看一下效果啊。最终程序运行效果如下。


    (说明:下面的操作都会和坐标有关,这里请先进行操作,我们在下一节将会讲解坐标系统。)

    二、利用更改坐标原点实现平移。

    Qpainter类中的translate()函数实现坐标原点的改变,改变原点后,此点将会成为新的原点(0,0);

    例如:

    void Dialog::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        QPixmap pix;
        pix.load(“images/linux.jpg”);
        painter.drawPixmap(0,0,100,100,pix);

        painter.translate(100,100); //将(100,100)设为坐标原点
        painter.drawPixmap(0,0,100,100,pix);
    }

    这里将(100,100)设置为了新的坐标原点,所以下面在(0,0)点贴图,就相当于在以前的(100,100)点贴图。效果如下。


    三、实现图片的缩放。

    我们可以使用QPixmap类中的scaled()函数来实现图片的放大和缩小。

    例如:

    void Dialog::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        QPixmap pix;
        pix.load(“images/linux.jpg”);
        painter.drawPixmap(0,0,100,100,pix);

        qreal width = pix.width(); //获得以前图片的宽和高
        qreal height = pix.height();

        pix = pix.scaled(width*2,height*2,Qt::KeepAspectRatio);
        //将图片的宽和高都扩大两倍,并且在给定的矩形内保持宽高的比值
        painter.drawPixmap(100,100,pix);
    }

    其中参数Qt::KeepAspectRatio,是图片缩放的方式。我们可以查看其帮助。将鼠标指针放到该代码上,当出现F1提示时,按下F1键,这时就可以查看其帮助了。当然我们也可以直接在帮助里查找该代码。


    这是个枚举变量,这里有三个值,只看其图片就可大致明 白,Qt::IgnoreAspectRatio是不保持图片的长宽比,Qt::KeepAspectRatio是在给定的矩形中保持长宽比,最后一个也 是保持长宽比,但可能超出给定的矩形。这里给定的矩形是由我们显示图片时给定的参数决定的,例如 painter.drawPixmap(0,0,100,100,pix);就是在以(0,0)点为起始点的宽和高都是100的矩形中。

    程序运行效果如下。


    四、实现图片的旋转。

    旋转使用的是QPainter类的rotate()函数,它默认是以原点为中心进行旋转的。我们要改变旋转的中心,可以使用前面讲到的translate()函数完成。

    例如:

    void Dialog::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        QPixmap pix;
        pix.load(“images/linux.jpg”);
        painter.translate(50,50); //让图片的中心作为旋转的中心
        painter.rotate(90); //顺时针旋转90度
        painter.translate(-50,-50);
     //使原点复原
        painter.drawPixmap(0,0,100,100,pix);
    }

    这里必须先改变旋转中心,然后再旋转,然后再将原点复原,才能达到想要的效果。

    运行程序,效果如下。


    五、实现图片的扭曲。

    实现图片的扭曲,是使用的QPainter类的shear(qreal sh,qreal sv)函数完成的。它有两个参数,前面的参数实现横行变形,后面的参数实现纵向变形。当它们的值为0时,表示不扭曲。

    例如:

    void Dialog::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        QPixmap pix;
        pix.load(“images/linux.jpg”);
        painter.drawPixmap(0,0,100,100,pix);
        painter.shear(0.5,0); //横向扭曲
        painter.drawPixmap(100,0,100,100,pix);
    }

    效果如下:

    其他扭曲效果:

    painter.shear(0,0.5); //纵向扭曲                           

    painter.shear(0.5,0.5); //横纵扭曲

                 

    图片形状的变化,其实就是利用坐标系的变化来实现的。我们在下一节中将会讲解坐标系统。这一节中的几个函数,我们可以在其帮助文件中查看其详细解释。
    展开全文
  • QTransform Qt坐标转换

    千次阅读 2017-08-15 15:55:45
    QTransform类定义了一个特定的用于2D坐标转换。 它的转换包括如何对坐标系统位置迁移,缩放,扭曲,旋转等,它在渲染图片中被用的非常多。 QTransform不同于QMatrix 它是一个真是的3*3的矩阵,允许进行可视化...

    QTransform类定义了一个特定的用于2D坐标转换。


    它的转换包括如何对坐标系统位置迁移,缩放,扭曲,旋转等,它在渲染图片中被用的非常多。

    QTransform不同于QMatrix 它是一个真是的3*3的矩阵,允许进行可视化的转换。

    QTransform的toAffine()的方法允许QTransform转换为QMatrix. 如果一个可视化的转换被用在特定的matrix, 这个转换将会导致一些数据的丢失。


    QTransform是Qt推荐使用的转换类。

    一个QTransform对象可以通过使用setMatrix(), scale(), rotate(), translate(), shear()等函数来构建。也就是说,它可以通过应用基础的矩阵操作来构建。这个矩阵可以在构建的时候定义,同事可以通过reset()函数来重置为默认的矩阵。


    QTransform类支持图形原始数据的映射:一个给定的点,线,不规则图形,区域或者是绘制的路径通过matrix定义的数据通过map()函数都可以映射到坐标系统。

    一个矩形的坐标可以通过mapRect()函数来进行转换,也可以通过mapToPolygon()函数转换为一个多边形。


    QTransform提供了一个isIdentity()函数,如果这个matrix是个可以识别的matrix就会返回true, 同时isInvertible()函数也返回true,如果这个矩阵是一个非奇异矩阵。这个函数会返回倒数矩阵,如果它是可倒的话,同时adjoint()会返回该矩阵的经典伴随矩阵。determinant()函数将会返回这个矩阵的行列式。



    展开全文
  • QT坐标转换——旋转

    2019-09-28 15:54:40
    关于图元的旋转问题,之前也查询了许多资料,都是利用rotate()函数进行操作的。 1.voidQPainter::rotate(qrealangle): 以原点为旋转中心,顺时针水平旋转... 实现绕坐标轴的旋转,两个坐标在分别为:XAxis,YA...

         关于图元的旋转问题,之前也查询了许多资料,都是利用rotate()函数进行操作的。

      1.void QPainter::rotate(qreal angle):

      以原点为旋转中心,顺时针水平旋转一定角度;

      2.void QTransform::rotate(qreal angle,Qt::Axis):

      实现绕坐标轴的旋转,两个坐标在分别为:XAxis,YAxis。

     

        本次实现的效果是图元绕X轴旋转180度,其代码如下:

      QTransform transform;

      transform.rotate(180,Qt::XAxis);//绕x轴旋转180度

      item->setTransform(transform);//将所有图元都添加转换

     

      结果:

    (转换前)

     

    (转换后)

     

     

     

     

     

    转载于:https://www.cnblogs.com/Ivy-yang/p/tuzi-rotate.html

    展开全文
  • 主题具体内容:QT 坐标转换 实现图片旋转等 时间:2011-11-06 04:28来源:未知 作者:admin 点击: 次 , 香港六合彩公司 一、应用QPixmap显示图片。 1.将以前的工程文件夹进行复制备份,我们这里将工程文件夹改名为...
  • 转 https://blog.csdn.net/hgcprg/article/details/53537106 转载于:https://www.cnblogs.com/m-zhang-yang/p/10537187.html
  • Win32消息的屏幕坐标如何转换Qt坐标 偶尔一些情况,需要将Win32 API获取到的鼠标位置转换到Qt的窗口坐标中,常见的方法是除以当前窗口的缩放(QPaintDevice::devicePixelRatioF或者其他),这样做是不准确的,只适合...
  • 世界坐标系原点在视图左上角,本例子通过世界坐标转换,将坐标原点定位在视图中央,Y轴向上,X轴向右,并绘制坐标轴,基于逻辑坐标系下的绘图,可将转换关系函数取消生效,对比世界坐标系下的绘图。 重写...
  • 大地测量课程作业,布尔沙模型的坐标转换,以及空间和大地坐标之间的转换,用Qt在mingw下写的,有啥问题私我,新人哪做的不好求轻喷和关照谢谢
  • Qt写的求七参数和大地测量坐标系与空间坐标转换,足以应付课程作业等
  • 没有复杂的变换,简单转化窗口坐标系,即可按我们正常熟知的... m_pPainter.setBrush(Qt::yellow); m_pPainter.drawRect(0, 0, 50, 50); m_pPainter.translate(100, 100); //将点(100,100)设为原点 m_pPainter...
  • 在绘制图形的时候,很多图形对象存储的坐标是数学上笛卡尔坐标,这个时候需要转换QT转换我开始迷茫,后面终于明白了,只要一个函数就搞定了。下面函数就是把屏幕坐标做下角定为(0,0),X轴向右,Y轴向上。此...
  • Qt 坐标系统

    2020-01-02 19:36:25
    坐标系统 以屏幕的左上角为原点即(0, 0)点,从左向右为x轴正向,从上向下为y轴正向,这整个屏幕的坐标系统就用来定位顶层窗口; 此外,窗口内部也有自己的坐标系统,它依然以左上角作为原点,从左向右为x轴正向,...
  • Qt 绘图坐标转换

    2019-07-06 22:23:22
    Qt 绘图坐标转换 先上一段代码,简单的画了个实心矩形 QPainter paint(this); paint.setBrush(Qt::yellow); paint.drawRect(0.0, 0.0, 100, 100); //绘制原点为(0.0,0.0),长宽为100的矩形 效果如图...
  • 我使用的是c++开发,没有使用到qml,所以不介绍qml的方法,arcgis for qt不像谷歌地图那些api,直接调用接口就可以获取当前坐标,并且默认就给你wgs84坐标。 arcgis for qt有一个接口就是 MapGraphicsView->...
  • Qt 坐标变换

    2021-03-08 20:38:34
    1.坐标变换常用接口 void translate(qreal dx,qreal dy) 平移 void rotate(qreal angle) 旋转 void scale(qreal sx,qreal sy) 缩放 void save 保存painter当前的状态 void restore() 恢复上...
  • QT坐标系统

    2020-05-19 18:11:17
    Qt中的三类坐标一般是先获得全局坐标,然后将其转换为另外两类坐标。 如果是顶层窗口为转换对象,则转换成窗口坐标;如果是控件为转换对象,则转换成控件坐标。 具体实现 然后整个坐标的获取是在鼠标移动事件里面...
  • Qt窗口与视口坐标转换

    千次阅读 2014-03-24 22:03:49
    所谓视口与其物理坐标 ,就是指在屏幕上的看到的实际的一个个像素和其坐标,而所谓窗口和逻辑坐标,就是指我们指定了一个这个窗体的坐标系,在这个坐标系内做的东西是先在其内画好,在转换到物理坐标系内去。...
  • Qt坐标系统

    2017-12-25 20:38:04
    在经历过实际操作,以及前面一节中我们见到的那个translate()函数之后,我们可以详细了解下 Qt坐标系统了。泛泛而谈坐标系统,有时候会觉得枯燥无味,难以理解,好在现在我们已经有了基础。 坐标系统是由...
  • QT 坐标变换

    2018-04-11 18:35:08
    QT 坐标变换 基本变换 &nbsp;&nbsp;默认的,QPainter在相关设备的坐标系统上进行操作,但是完全支持仿射坐标变换.绘图时可以使用QPainter::scale()函数缩放坐标系统,使用QPainter::rotate()函数顺时针旋转...
  • QT 坐标系统理解

    万次阅读 多人点赞 2016-12-09 11:45:58
    这几天学习QT的2D绘图,可因为坐标系统把我拦住了。不但资料少,而且这些资料都是内容雷同。本来这是件非常简单的事情,却有种越描越黑的感觉。经过几天的折腾,总算是理解了这层关系。现在总结一下,不要让大家再走...
  • 在QT5.1.1里加载离线地图,在html文件里做坐标转换总是实现不了,又不能调试,索性在QT里做,直接在地图上画出来,资源里包含qt坐标转换的代码及html文件
  • Qt动画与Qt坐标小记

    2016-01-23 18:35:24
    今天做项目过程中,想要Qt实现类似于会声会影或者移动应用的转场效果,即界面动画效果。通过动画类QpropertyAnimation,将界面属性进行动画,实现了简单的动画效果,包括弹跳式转场,切入式效果等。使得程序界面切换...
  • Qt坐标

    2019-09-27 18:03:21
    这几天学习QT的2D绘图,可因为坐标系统把我拦住了。不但资料少,而且这些资料都是内容雷同。本来这是件非常简单的事情,却有种越描越黑的感觉。经过几天的折腾,总算是理解了这层关系。现在总结一下,不要让大家再走...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,134
精华内容 2,453
关键字:

qt坐标转换