【问题标题】:QGraphicsItemGroup.removeFromGroup -- child items not correctly reparented to SceneQGraphicsItemGroup.removeFromGroup - 子项目没有正确地重新设置为场景
【发布时间】:2014-02-08 03:34:26
【问题描述】:

我正在尝试从 QGraphicsItemGroup 中删除 QGraphicsItem。当调用 removeFromGroup 时,该项目被删除(当然)。但是,它在场景中不再可见。我必须调用 Scene.addItem(item) 才能让它再次出现。这显然是你不应该做的事情(我被警告这样做)。但我似乎找不到另一种解决方法。

这是一个最小的例子:

import sys 

from PyQt4.QtGui import *
from PyQt4.QtCore import *

class MainWindow(QMainWindow):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.view = QGraphicsView()
        self.scene = QGraphicsScene()
        self.view.setScene(self.scene)

        self.setCentralWidget(self.view)


def add_group(scene):
    group = QGraphicsItemGroup()
    text = QGraphicsTextItem()
    text.setPlainText("I'm visible")
    group.addToGroup(text)
    scene.addItem(group)

    # After this, text is no longer in group. However, it is no longer visible.
    group.removeFromGroup(text)
    assert not text in group.childItems()

    # But text is still in scene. 
    assert text.scene() == scene

    # this works (i.e. text becomes visible again). However, it also produces a 
    # warning: QGraphicsScene::addItem: item has already been added to this scene. 
    # The docs also advice against it.
    scene.addItem(text)

    # According to the docs, I thought this might work, but it gives me a TypeError.
    # text.setParentItem(0)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = MainWindow()
    add_group(main.scene)
    main.show()
    sys.exit(app.exec_())

非常欢迎提示和提示。

【问题讨论】:

  • 在添加到组之前尝试将文本项添加到场景中
  • 感谢您的建议,但(至少在这里)没有什么不同。
  • 从组中移除后尝试设置项目的位置。

标签: python qt pyqt


【解决方案1】:

QGraphicsTextItem 永远不能作为场景的父级,因为它的父级必须是 QGraphicsItem(QGraphicsScene 不继承)。

当 QGraphicsTextItem 创建时,它的父对象是None。它的父级在添加到它时设置为group(QGraphicsItemGroup 是QGraphicsItem 的子类),然后在从group 中删除时设置回None

调用scene.addItem() 实际上是一个NO-OP。 Qt 检查scene 是否与text.scene() 相同,如果相同,则打印警告并不做任何操作返回。

在某些情况下它似乎“工作”的事实只是 python 垃圾收集机制的产物。

如果您的测试以更真实的方式重新投射,则 QGraphicsTextItem 在从组中移除后仍然可见:

import sys

from PyQt4.QtGui import *
from PyQt4.QtCore import *

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.view = QGraphicsView(self)
        self.scene = QGraphicsScene(self.view)
        self.view.setScene(self.scene)
        self.setCentralWidget(self.view)
        self.group = QGraphicsItemGroup()
        self.text = QGraphicsTextItem()
        self.text.setPlainText("I'm visible")
        self.group.addToGroup(self.text)
        self.scene.addItem(self.group)
        self.group.removeFromGroup(self.text)

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

【讨论】:

    【解决方案2】:

    问题是text被删除了,因为你从组中删除它后没有任何引用,试试这个:

    ...
    text = QGraphicsTextItem()
    scene.text = text #just to keep the reference, ideally should be self.text = text
    ...
    

    现在你不需要scene.addItem(text)

    【讨论】:

      猜你喜欢
      • 2012-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-16
      • 1970-01-01
      • 1970-01-01
      • 2012-01-02
      • 1970-01-01
      相关资源
      最近更新 更多