user1971541
user1971541

Reputation: 31

Rotating a pixmap in pyqt4 gives undesired translation

I'm trying to write a simple application that rotates a png image when a button is pressed. I have it all working fine except that as the image rotates it deviates from it's centre in a south-east direction. I would have thought it wasn't rotating around its centre, but it returns to the origin every 45 degrees of rotation, which is strange.

On a key event I'm simply calling:

pixmap = pixmap.transformed(QtGui.QTransform().rotate(-self.rot), QtCore.Qt.SmoothTransformation)

Is there a way to set the origin of the transformation to stop the image moving around?

Upvotes: 3

Views: 6250

Answers (1)

Jean-Sébastien
Jean-Sébastien

Reputation: 2697

A simple solution, if you are using a QLabel to draw the QPixmap, is to set the alignment of the QLabel to AlignCenter. Moreover, to avoid an initial resizing of the QLabel during the first 45 degrees of the image rotation, the minimum size of the QLabel can be set to the value of the pixmap's diagonal. The image should then properly rotate around its centre without any unwanted back-and-forth translation.

Below I demonstrate how this can be done in a simple application:

import sys
from PyQt4 import QtGui, QtCore
import urllib

class myApplication(QtGui.QWidget):
    def __init__(self, parent=None):
        super(myApplication, self).__init__(parent)

        #---- Prepare a Pixmap ----

        url = ('http://sstatic.net/stackexchange/img/logos/' +
               'careers/careers-icon.png?v=0288ba302bf6')
        self.img = QtGui.QImage()
        self.img.loadFromData(urllib.urlopen(url).read())

        pixmap = QtGui.QPixmap(self.img)

        #---- Embed Pixmap in a QLabel ----

        diag = (pixmap.width()**2 + pixmap.height()**2)**0.5

        self.label = QtGui.QLabel()
        self.label.setMinimumSize(diag, diag)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setPixmap(pixmap)

        #---- Prepare a Layout ----

        grid = QtGui.QGridLayout()

        button = QtGui.QPushButton('Rotate 15 degrees')
        button.clicked.connect(self.rotate_pixmap)

        grid.addWidget(self.label, 0, 0)
        grid.addWidget(button, 1, 0)

        self.setLayout(grid)

        self.rotation = 0

    def rotate_pixmap(self):

        #---- rotate ----

        # Rotate from initial image to avoid cumulative deformation from
        # transformation

        pixmap = QtGui.QPixmap(self.img)
        self.rotation += 15

        transform = QtGui.QTransform().rotate(self.rotation)
        pixmap = pixmap.transformed(transform, QtCore.Qt.SmoothTransformation)

        #---- update label ----

        self.label.setPixmap(pixmap)

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)

    instance = myApplication()  
    instance.show()    

    sys.exit(app.exec_())

Which results in:

enter image description here

Alternatively, this post : can't get the image to rotate in center in Qt, seems to address your issue if you are painting the QPixmap directly with QPainter.

Upvotes: 6

Related Questions