PyQt5:关于 QGraphicsScene 的 itemAt() 和 focusItemChanged() 的问题

2024-01-27

我有两个问题:

  1. itemAt() 中的 QTransform() 是什么意思?下面这句话是Qt doc中的内容,但我无法理解:

deviceTransform 是应用于视图的变换,如果场景包含忽略变换的项目,则需要提供。

  1. 为什么 focusItemChanged 信号不起作用?

这是我的代码:

import sys
from PyQt5.QtGui import QTransform
from PyQt5.QtWidgets import QApplication, QGraphicsItem, QGraphicsScene, QGraphicsView


class Demo(QGraphicsView):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(300, 300)

        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 300, 300)

        self.rect = self.scene.addRect(100, 30, 100, 30)
        self.ellipse = self.scene.addEllipse(100, 80, 50, 40)

        self.rect.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable)
        self.ellipse.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable)

        self.setScene(self.scene)

        # Question 1
        print(self.scene.itemAt(110, 40, QTransform()))

        # Question 2
        self.scene.focusItemChanged.connect(self.my_slot)

    def my_slot(self, new_item, old_item):
        print(new_item)
        print(old_item)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

任何帮助,将不胜感激。


1.itemAt()中的QTransform()是什么意思?

正如它指出的那样,如果有一个项目忽略转换,则只需要传递 deviceTransform ,那么如何做到让项目不支持转换呢?您必须启用该标志Qt::ItemIgnoresTransformations.

使用您的代码,您看不到差异,因此我实现了以下示例,其中有 2 个项目,其中一个项目激活了 ItemIgnoresTransformations 标志,另一个则没有。然后,当您按下任何项目时,预计该项目将在控制台中打印,但如果您传递 QTransform (),如果您按下单选按钮传递 viewportTransform,您将看到具有 ItemIgnoresTransformations 标志的项目返回 None () 你会看到现在这两项都打印在控制台上。因此,如果有任何项目启用了 ItemIgnoresTransformations 标志,则必须传递 deviceTransform。

import sys
from PyQt5 import QtCore, QtGui, QtWidgets


class Demo(QtWidgets.QGraphicsView):
    def __init__(self):
        super(Demo, self).__init__()
        self._scene = QtWidgets.QGraphicsScene()
        self._scene.setSceneRect(0, 0, 300, 300)
        self.setScene(self._scene)
        self.rect1 = self._scene.addRect(
            100, 30, 100, 30, brush=QtGui.QBrush(QtGui.QColor("red"))
        )
        self.rect1.setFlag(QtWidgets.QGraphicsItem.ItemIgnoresTransformations)

        self.rect2 = self._scene.addRect(
            200, 30, 100, 30, brush=QtGui.QBrush(QtGui.QColor("green"))
        )

        self.rotate(50)
        self._use_deviceTransform = False

    def mousePressEvent(self, event):
        sp = self.mapToScene(event.pos())
        item = self._scene.itemAt(
            sp,
            self.viewportTransform()
            if self._use_deviceTransform
            else QtGui.QTransform(),
        )
        print(item)

    def set_use_deviceTransform(self, t):
        self._use_deviceTransform = t


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    radiobutton = QtWidgets.QRadioButton("use deviceTransform")
    demo = Demo()
    radiobutton.toggled.connect(demo.set_use_deviceTransform)
    w = QtWidgets.QWidget()
    lay = QtWidgets.QVBoxLayout(w)
    lay.addWidget(radiobutton)
    lay.addWidget(demo)
    w.show()
    w.resize(640, 480)
    sys.exit(app.exec_())

2.为什么focusItemChanged信号不起作用?

如果项目的焦点发生变化,则会触发信号,但默认情况下项目没有焦点,因此不会发出信号,解决方案是激活标志QGraphicsItem::ItemIsFocusable:

import sys
from PyQt5.QtGui import QTransform
from PyQt5.QtWidgets import QApplication, QGraphicsItem, QGraphicsScene, QGraphicsView
from PyQt5.QtCore import pyqtSlot, Qt


class Demo(QGraphicsView):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(300, 300)

        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 300, 300)

        self.rect = self.scene.addRect(100, 30, 100, 30)
        self.ellipse = self.scene.addEllipse(100, 80, 50, 40)

        self.rect.setFlags(
            QGraphicsItem.ItemIsMovable
            | QGraphicsItem.ItemIsSelectable
            | QGraphicsItem.ItemIsFocusable
        )
        self.ellipse.setFlags(
            QGraphicsItem.ItemIsMovable
            | QGraphicsItem.ItemIsSelectable
            | QGraphicsItem.ItemIsFocusable
        )

        self.setScene(self.scene)
        self.scene.focusItemChanged.connect(self.my_slot)

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

PyQt5:关于 QGraphicsScene 的 itemAt() 和 focusItemChanged() 的问题 的相关文章

  • xlrd.biffh.XLRDError:Excel xlsx 文件;不支持[重复]

    这个问题在这里已经有答案了 我正在尝试使用读取启用宏的 Excel 工作表pandas read excel与 xlrd 库 它在本地运行良好 但是当我尝试将其推送到 PCF 时 我收到此错误 2020 12 11T21 09 53 441
  • 切片稀疏(scipy)矩阵

    我将不胜感激任何帮助 以理解从 scipy sparse 包中切片 lil matrix A 时的以下行为 实际上 我想根据行和列的任意索引列表提取子矩阵 当我使用这两行代码时 x1 A list 1 x2 x1 list 2 一切都很好
  • JavaScript 相当于 Python 的参数化 string.format() 函数

    这是 Python 示例 gt gt gt Coordinates latitude longitude format latitude 37 24N longitude 115 81W Coordinates 37 24N 115 81W
  • 从Python中的字符串中提取货币金额

    我正在制作一个程序 从字符串中获取货币并将其转换为其他货币 例如 如果字符串是 the car cost me 13 250 我需要得到 and 13250 我已经有了这个正则表达式 1 确实如此 但是该字符串很有可能有多个价格 并且全部使
  • Kivy - 文本换行工作错误

    我正在尝试在 Kivy 1 8 0 应用程序中换行文本 当没有太多文字时 一切正常 但如果文本很长并且窗口不是很大 它只是剪切文本 这是示例代码 vbox BoxLayout orientation vertical size hint y
  • 使用 Django Rest 保存 Base64ImageField 类型会将其保存为原始图像。如何将其转换为普通图像

    我的模型中有 5 个图像字段 imageS imageS imageS imageS 和 imageE 我正在尝试按以下方式保存图像 图像的类型Base64ImageField images imageA imageB imageC ima
  • 登录网站并使用 python 请求下载文件

    我有一个带有 HTML 表单的网站 登录后 它会将我带到 start php 站点 然后将我重定向到overview php 我想从该服务器下载文件 当我单击 ZIP 文件的下载链接时 链接后面的地址是 getimage php path
  • Python Pandas 根据另一列的总计从另一个数据帧中选择值

    我下面有一个 DataFrame 但我需要根据取消和订单列从每个代码中选择行 假设代码 xxx 的阶数为 6 1 5 1 阶数为 11 我需要一种算法 可以选择满足总共 11 行的行 阶数为 6 5 如果没有行匹配 则选择最接近的 id 并
  • PySide6.1 与 matplotlib 3.4 不兼容

    当我只安装PySide6时 GUI程序运行良好 但是一旦我安装了matplotlib及其依赖包 包括pyqt5 则GUI程序将无法运行并输出以下错误消息 This application failed to start because no
  • 在Python中计算内存碎片

    我有一个长时间运行的进程 不断分配和释放对象 尽管正在释放对象 但 RSS 内存使用量会随着时间的推移而增加 如何计算发生了多少碎片 一种可能性是计算 RSS sum of allocations 并将其作为指标 即便如此 我该如何计算分母
  • 如何使用 paramiko 查看(日志)文件传输进度?

    我正在使用 Paramiko 的 SFTPClient 在主机之间传输文件 我希望我的脚本打印文件传输进度 类似于使用 scp 看到的输出 scp my file user host user host password my file 1
  • 如何使用 sys.path.append 在 Python 中导入文件?

    我的桌面上有两个目录 DIR1 and DIR2其中包含以下文件 DIR1 file1 py DIR2 file2 py myfile txt 这些文件包含以下内容 file1 py import sys sys path append s
  • 使用 numpy 在 python 中执行最大方差旋转

    我正在研究矩阵的主成分分析 我已经找到了如下所示的组件矩阵 A np array 0 73465832 0 24819766 0 32045055 0 3728976 0 58628043 0 63433607 0 72617152 0 5
  • Pandas style.bar 颜色基于条件?

    如何渲染其中一列的 Pandas dfstyle bar color属性是根据某些条件计算的 Example df style bar subset before after color ff781c vmin 0 0 vmax 1 0 而
  • Python 类型安全吗?

    根据维基百科 https en wikipedia org wiki Type system Type safety and memory safety 如果一种语言不允许违反类型系统规则的操作或转换 计算机科学家就认为该语言是 类型安全的
  • 检测 IDLE 的存在/如何判断 __file__ 是否未设置

    我有一个脚本需要使用 file 所以我了解到 IDLE 没有设置这个 有没有办法从我的脚本中检测到 IDLE 的存在 if file not in globals file is not set 如果你想做一些特别的事情 file 未设置
  • Python:高精度time.sleep

    你能告诉我如何在 Win32 和 Linux 上的 Python 2 6 中获得高精度睡眠函数吗 您可以在中使用浮点数sleep http docs python org library time html time sleep 该参数可以
  • Django 模型:如何使用 mixin 类来覆盖 django 模型以实现 save 等功能

    我想在每次保存模型之前验证值 所以 我必须重写保存函数 代码几乎是一样的 我想把它写在 mixin 类中 但失败了 我不知道如何写 super func 我英语不好 抱歉 class SyncableMixin object def sav
  • 如何为所有用户安装 Anaconda python?

    Anaconda python 发行版 https store continuum io cshop anaconda 非常方便地部署科学计算环境 SCE 并根据需要切换python版本 默认情况下 安装会将 python 定位到 anac
  • 缓存 Flask-登录 user_loader

    我有这个 login manager user loader def load user id None return User query get id 在我引入 Flask Principal 之前它运行得很好 identity loa

随机推荐