Results 1 to 2 of 2

Thread: Rotate a QGraphicsPixmapItem with a rotation handle PyQt5

  1. #1

    Default Rotate a QGraphicsPixmapItem with a rotation handle PyQt5

    I’m writing an application in PyQt5 that will allow the user to rotate a QGraphicsPixmapItem and also delete it. The rotation needs to be with the mouse via a rotation handle that the user can grab with the mouse and rotate, thus rotating the QGraphicsPixmapItem. I need the handle to have a fixed distance to the item position, precisely to be at the top left corner of the QGraphicsPixmapItem. Also, I need the handle to be a child of the graphic pixmap item so that when the user moves the image or deletes it, the handle will be moved or deleted too.
    I have some troubles, when I do not set the handle as a child of the graphic pixmap item, the rotation is fine but not the part of moving the handle when the user moves the image. When I set the handle as a child, the rotation doesn’t work as I want.
    Could someone help me please? This is my code:

    Qt Code:
    1. import sys
    2. from PyQt5.QtWidgets import QMainWindow, QApplication, QGraphicsView
    3. from PyQt5 import QtGui, QtWidgets
    4. import math
    6. class MainWindow(QMainWindow):
    7. def __init__(self, parent=None):
    8. super(MainWindow, self).__init__(parent)
    10. self.scene = Scene()
    11. self.view = QGraphicsView(self)
    12. self.setGeometry(10, 30, 850, 600)
    13. self.view.setGeometry(20, 22, 800, 550)
    14. self.view.setScene(self.scene)
    16. class Scene(QtWidgets.QGraphicsScene):
    17. def __init__(self, parent=None):
    18. super(Scene, self).__init__(parent)
    19. # other stuff here
    20. self.set_image()
    22. def set_image(self):
    23. photo = Photo()
    24. self.addItem(photo)
    25. photo.set_pixmap()
    27. class Photo(QtWidgets.QGraphicsPixmapItem):
    28. def __init__(self, parent=None):
    29. super(Photo, self).__init__(parent)
    31. self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
    32. self.setTransformOriginPoint(self.boundingRect().center())
    34. def set_pixmap(self):
    35. pixmap = QtGui.QPixmap("perro.jpg")
    36. self.setPixmap(pixmap)
    37. self.pixmap_controller = PixmapController(self)
    38. self.scene().addItem(self.pixmap_controller)
    39. self.pixmap_controller.set_pixmap_controller()
    40. self.pixmap_controller.setPos(self.boundingRect().topLeft())
    41. self.pixmap_controller.setFlag(QtWidgets.QGraphicsItem.ItemSendsScenePositionChanges, True)
    43. def rotate_item(self, position):
    44. item_position = self.transformOriginPoint()
    45. angle = math.atan2(item_position.y() - position.y(), item_position.x() - position.x()) / math.pi * 180 - 45
    46. print(angle)
    47. self.setRotation(angle)
    48. self.setPos(position)
    50. class PixmapController(QtWidgets.QGraphicsEllipseItem):
    51. def __init__(self, pixmap):
    52. super(PixmapController, self).__init__(parent=pixmap)
    53. self.pixmap = pixmap
    55. self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
    56. color = QtGui.QColor(0, 0, 0)
    57. brush = QtGui.QBrush(color)
    58. self.setBrush(brush)
    60. def set_pixmap_controller(self):
    61. self.setRect(-5, -5, 10, 10)
    63. def itemChange(self, change, value):
    64. if change == QtWidgets.QGraphicsItem.ItemPositionChange:
    65. self.pixmap.rotate_item(value)
    66. return super(PixmapController, self).itemChange(change, value)
    68. if __name__ == "__main__":
    69. app = QApplication(sys.argv)
    70. window = MainWindow()
    72. sys.exit(app.exec_())
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2008
    Alameda, CA, USA
    Thanked 864 Times in 851 Posts
    Qt products

    Default Re: Rotate a QGraphicsPixmapItem with a rotation handle PyQt5

    I am not a PyQt5 expert, but I see a few questionable things.

    Zeroth: You are using the name "pixmap" to refer to two completely different things: a QPixmap (inside the Photo class) and the parent Photo instance (inside the PixmapController class). This is really confusing and when I first read your code I thought you were making a copy of the QPixmap. It would be more clear (and probably less confusing to you also) if you changed the name to "photo" in the PixmapController class to make it clear you are manipulating the parent object.

    First, I think you should be creating your PixmapController instance in the Photo constructor. You don't need to create a new one every time your load the pixmap, you just need to move the existing one so it is at the top left corner of the new pixmap.

    Second, it doesn't seem to me that you are keeping the handle position at the top left when you rotate. When you process the ItemPositionChange signal, you do rotate the parent, but then you call the superclass method which will move the handle relative to the Photo. I think you should only be calling the superclass method when the change is not an ItemPositionChange.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. Replies: 0
    Last Post: 26th October 2020, 18:30
  2. Qt screen rotation in QML
    By MGlolenstine in forum Qt for Embedded and Mobile
    Replies: 0
    Last Post: 16th January 2020, 16:09
  3. resize and rotate handle
    By Noxxik in forum Qt Programming
    Replies: 5
    Last Post: 22nd February 2009, 15:03
  4. Rotation on Qframe
    By Pharell in forum Qt Programming
    Replies: 11
    Last Post: 2nd April 2008, 17:31
  5. Rotate QGraphicsPixmapItem
    By durbrak in forum Qt Programming
    Replies: 7
    Last Post: 15th April 2007, 15:51

Tags for this Thread


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.