用鼠标旋转QGraphicsPixmapItem

2023-12-03

我正在 PyQt 中编写一个应用程序,允许用户选择 图像放置在QGraphicsScene(使用自定义QGraphicsPixmapItem)。选择后我想要一个旋转手柄 出现在用户可以用鼠标“抓取”的图像上, 旋转,从而旋转QGraphicsPixmapItem。基本上,我正在寻找 对于您在 PowerPoint 中选择的旋转手柄功能 形状。这似乎是很多人都会的一个非常基本的功能 已经实现了,但我在网上找不到任何好的例子。能 有人指出我正确的方向吗?


让我们首先将问题分成较小的问题,然后再次将所有内容组合起来。我在此解决方案中使用 PyQt5。

1. 旋转一个QGraphicsItem

为此,您需要使用以下命令设置旋转角度(以度为单位)setRotation在该项目上。旋转将围绕由指定的点进行setTransformOriginPoint。通常,一个会占据形状的中心。如果不指定该点,通常会采用形状的左上角。

2. 拖动一个QGraphicsItem

出于性能原因,QGraphicsItem 不可移动,并且不会将位置更改发送到事件框架。通过设置适当的标志QtWidgets.QGraphicsItem.ItemIsMovable | QtWidgets.QGraphicsItem.ItemSendsScenePositionChanges你可以改变这一点。此外QGraphicsItem不继承自QObject,因此为了使用信号,我通常有一个继承自 QObject 的附加对象。

3.绘制一个手柄项并确定要旋转的旋转角度

在下面的示例中,我有一个非常小的矩形作为句柄,您当然可以使用您喜欢的任何 QGraphicsItem。我的方法make_GraphicsItem_draggable接受任何 QGraphicsItem 派生类并使其可拖动。为了确定给定可拖动手柄项目的当前位置和要旋转的项目的变换原点的旋转角度,请使用math.atan2以及差异x and y这些位置的坐标。

Example

import math
from PyQt5 import QtCore, QtWidgets

class DraggableGraphicsItemSignaller(QtCore.QObject):

    positionChanged = QtCore.pyqtSignal(QtCore.QPointF)

    def __init__(self):
        super().__init__()

def make_GraphicsItem_draggable(parent):

    class DraggableGraphicsItem(parent):

        def __init__(self, *args, **kwargs):
            """
            By default QGraphicsItems are not movable and also do not emit signals when the position is changed for
            performance reasons. We need to turn this on.
            """
            parent.__init__(self, *args, **kwargs)
            self.parent = parent
            self.setFlags(QtWidgets.QGraphicsItem.ItemIsMovable | QtWidgets.QGraphicsItem.ItemSendsScenePositionChanges)
            self.signaller = DraggableGraphicsItemSignaller()

        def itemChange(self, change, value):
            if change == QtWidgets.QGraphicsItem.ItemPositionChange:
                self.signaller.positionChanged.emit(value)

            return parent.itemChange(self, change, value)

    return DraggableGraphicsItem

def rotate_item(position):
    item_position = item.transformOriginPoint()
    angle = math.atan2(item_position.y() - position.y(), item_position.x() - position.x()) / math.pi * 180 - 45 # -45 because handle item is at upper left border, adjust to your needs
    print(angle)
    item.setRotation(angle)


DraggableRectItem = make_GraphicsItem_draggable(QtWidgets.QGraphicsRectItem)

app = QtWidgets.QApplication([])

scene = QtWidgets.QGraphicsScene()
item = scene.addRect(0, 0, 100, 100)
item.setTransformOriginPoint(50, 50)

handle_item = DraggableRectItem()
handle_item.signaller.positionChanged.connect(rotate_item)
handle_item.setRect(-40, -40, 20, 20)
scene.addItem(handle_item)

view = QtWidgets.QGraphicsView(scene)
view.setFixedSize(300, 200)
view.show()

app.exec_()

开始(项目 = 大矩形,手柄 = 小矩形)

Start

拖动手柄后旋转(小矩形)

Rotated

缺少一件事:手柄到项目位置没有固定距离(即,您可以将其拖得更远或更近,而不是绕圈移动)。虽然这不会改变旋转角度,但看起来并不完美。但这里涵盖了要点,应该能让您走上正确的道路。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用鼠标旋转QGraphicsPixmapItem 的相关文章

  • Qt程序部署到多平台,如何?

    我是 Qt 编程新手 我想开发一个程序 我想在 Windows Linux ubuntu 和 Mac 上运行 听说Qt支持多平台应用程序开发 但我的问题是 在我部署或编译后 任何 Qt 库都需要在 Ubuntu 中运行这个应用程序吗 如果您
  • QDesktopServices::openUrl 在资源管理器中选择指定文件

    在大多数编码程序中 您可以右键单击该项目 然后单击 在资源管理器中显示 它会在资源管理器中显示选定项目的文件 在 Qt 中使用 QDesktopServices 如何做到这一点 或在 QT 中执行此操作的任何方式 您可以使用此方法在 Win
  • (如何)我可以抑制未找到包配置文件的警告吗?

    我正在尝试创建一个CMakeLists txt尝试查找的文件Qt5 如果失败 则尝试回退到Qt4安装 该脚本到目前为止有效 但如果出现以下情况我总会收到警告Qt5未安装 注意FindQt5 cmake是由提供Qt5并且仅当以下情况时才可用Q
  • Qt:将拖放委托给子级的最佳方式

    我在 QWidget 上使用拖放 我重新实现了 DragEnterEvent dragLeaveEvent dragMoveEvent 和 dropEvent 效果很好 在我的 QWidget 中 我有其他 QWidget 子级 我希望它们
  • GoQt 致命错误:QAbstractAnimation:没有这样的文件或目录

    我尝试编译 Qt 来开发桌面应用程序 我按照 Qt 网站上的官方 wiki 指南的说明进行操作 当我尝试go run示例文件夹中的示例 我收到错误 去运行 home pinkya rabbit workspace go1programs s
  • Qt WinRT 应用程序无法访问文件权限被拒绝

    我需要使用 Qt 和 FFMPEG 开发 WinRT 应用程序 我根据指令构建了 WinRT 的 ffmpeghere https github com Microsoft FFmpegInterop我可以将库与我的项目链接起来 现在我需要
  • Qt - 如何粘合两个窗口并将它们移动在一起?

    就像qmmp Qt 音乐播放器ui设计一样 这两个或三个窗口实际上在同一个窗口中 因为只有一个dock图标 并且这些窗口可以一起移动并相互附着 我看了源码 好像有用QDockWidget 但我真的不知道如何获得它的细节 当您手动移动辅助窗口
  • QTextEdit.find() 在 Python 中不起作用

    演示问题的简单代码 usr bin env python import sys from PyQt4 QtCore import QObject SIGNAL from PyQt4 QtGui import QApplication QTe
  • 加权 Voronoi 的 CGAL 2D APOLLONIUS 图 - 如何生成和获取面和顶点?

    我正在尝试根据阿波罗尼乌斯图生成加权沃罗诺伊 我正在使用 CGAL 库 我找不到如何从 apollonius 获取面和顶点的好例子 我有以下类型定义 typedef double NT typedef CGAL Cartesian lt N
  • 错误 LNK2001:无法解析的外部符号 __CxxFrameHandler3

    我正在将 Qt 从 VS 2013 迁移到 Qt 5 10 1 到 VS 2015 出现以下多个链接错误 error LNK2001 unresolved external symbol CxxFrameHandler3 error LNK
  • 多 AVL 树旋转

    假设我有一个无序集合 s 3 6 5 1 2 4 并且我需要构造一个 AVL 树 就这么多了 我了解基本的旋转 我在这里达到这一点 5 2 6 1 3 但当我尝试插入 4 时 一切都崩溃了 我得到的最终答案是 左边的 4 But the a
  • 使用 Visual Studio 2013 构建 Qt 5.2.1 的静态版本

    几天来我一直在尝试使用 Visual Studio 2013 构建 Qt 的静态版本 我就是不明白我做错了什么 System Windows 7 64 位 Visual Studio 2013 仍安装 Visual Studio 2012
  • 为 Windows 98 编译 Qt

    我需要支持 Windows 98 Qt 文档声称这是可能的 但没有说明 Qt 4 6 的分布式二进制文件不能在 Win98 上运行 而且我采样的大多数 Qt 应用程序也不能在 Win98 上运行 对于几个确实在 98 上运行的应用程序 我询
  • 更改 Qt OpenGL 窗口示例以使用 OpenGL 3.3

    我正在尝试更改 Qt OpenGL 示例以使用更现代的 opengl 版本 330 似乎合适 所以我做了 在 main cpp 上设置版本和配置文件 设置着色器版本 更改着色器以使用统一 它现在构建没有任何错误 但我只看到一个空白窗口 我错
  • 如何获取 QTableView 的标题列表?

    我有一个QTableView我的对话框中的对象 我需要访问该表的水平标题并将它们放入QStringList object 尽管进行了大量搜索 但我在 Qt 文档中找不到如何获取此标头列表 编辑 我发现的最接近的地方是this https w
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • Qt 布局,在小部件大小更改后调整到最小大小

    基本上我有一个QGridLayout里面有一些小部件 最重要的是 2 个标签 我用它们将图像绘制到屏幕上 好吧 如果用户愿意 他可以更改传入图像的分辨率 从而强制标签调整大小 我们假设标签的初始大小是320x240 用户将 VideoMod
  • 更改QLineEdit的ClearButton图标

    我想在Windows 10 1909 64位 上的Python 3 8和PyQt5 5 15 0 上更改我的QLineEdit的ClearButton图标 稍后我想在Linux上运行代码 我尝试应用此处找到的代码 如何在 QLineEdit
  • 将 gnuplot 嵌入现有 QtWidget 中

    我正在用 C 创建一个 伪 实时绘图应用程序 使用 gnuplot 作为绘图后端 我的要求之一是绘图必须位于现有窗口内 而不是有一个单独的绘图窗口 gnuplot 默认为 Gnuplot 有一个选项可以指定 Qt 小部件 ID 这似乎适合我
  • 同时从多个流中捕获、最佳方法以及如何减少 CPU 使用率

    我目前正在编写一个应用程序 该应用程序将捕获大量 RTSP 流 在我的例子中为 12 个 并将其显示在 QT 小部件上 当我超过大约 6 7 个流时 问题就会出现 CPU 使用率激增并且出现明显的卡顿 我认为它不是 QT 绘制函数的原因是因

随机推荐