2014-02-07 93 views
2

我試圖從QGraphicsItemGroup中刪除QGraphicsItem。當調用removeFromGroup時,該項目被刪除(當然)。但是,它現在在場景中不再可見。我必須調用Scene.addItem(item)才能再次出現。這顯然是你不應該做的事情(我給出了這樣做的警告)。但我似乎無法找到另一種解決方法。QGraphicsItemGroup.removeFromGroup - 子項目沒有正確重新映射到場景

這裏有一個小例子:

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_()) 

技巧與提示都非常歡迎。

+0

嘗試添加文本項目現場將其添加到組 –

+0

感謝前這個建議,但是(至少在這裏)並沒有什麼不同。 – Henry

+0

嘗試在從組中移出後設置項目的位置。 – TheDarkKnight

回答

3

的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)