gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 07:58:31 26 4
gpt4 key购买 nike

我有两个问题:

  1. QTransform() 在 itemAt() 中意味着什么?下面这句话是Qt doc中的内容,但我看不懂:

deviceTransform is the transformation that applies to the view, and needs to be provided if the scene contains items that ignore transformations.

  • 为什么 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)

    关于python - PyQt5:关于 QGraphicsScene 的 itemAt() 和 focusItemChanged() 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55824951/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com