2010-03-04 79 views
1

我試圖保持放入QTreeWidgetItem一個小部件使用QTreeWidget.setItemWidget一個重新設置父級(拖放)()PyQt的QTreeWidget setItemWidget自敗後拖/放

但是,因此,如果您編譯以下後代碼 - 是QTreeWidgetItem中的小部件消失。 任何想法爲什麼?什麼代碼可以解決這個問題(與我猜的小部件重新填充QTreeWidgetItem?)

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


class InlineEditor (QWidget): 
    _MUTE = 'MUTE' 

    def __init__ (self, parent): 
     QWidget.__init__ (self, parent) 

     self.setAutoFillBackground (True) 
     lo = QHBoxLayout() 
     lo.setSpacing(4) 

     self._cbFoo = QComboBox() 
     for x in ["ABC", "DEF", "GHI", "JKL"]: 
      self._cbFoo.addItem(x) 

     self._leBar = QLineEdit('', self) 
     lo.addWidget (self._cbFoo, 3) 
     lo.addSpacing (5) 
     lo.addWidget (QLabel ('Bar:')) 
     lo.addWidget (self._leBar, 3) 
     lo.addStretch (5) 
     self.setLayout (lo) 

class Form (QDialog): 
    def __init__(self,parent=None): 
     QDialog.__init__(self, parent) 

     grid = QGridLayout() 
     tree = QTreeWidget() 

     # Here is the issue? 
     tree.setDragDropMode(QAbstractItemView.InternalMove) 

     tree.setColumnCount(3) 

     for n in range (2): 
      i = QTreeWidgetItem (tree) # create QTreeWidget the sub i 
      i.setText (0, "first" + str (n)) # set the text of the first 0 
      i.setText (1, "second") 
      for m in range (2): 
       j = QTreeWidgetItem(i) 
       j.setText (0, "child first" + str (m)) 

     #b1 = QCheckBox("push me 0", tree) # this wont work w/ drag by itself either 
     #tree.setItemWidget (tree.topLevelItem(0).child(1), 1, b1) 

     item = InlineEditor(tree) # deal with a combination of multiple controls 
     tree.setItemWidget(tree.topLevelItem(0).child(1), 1, item) 

     grid.addWidget (tree) 
     self.setLayout (grid) 

app = QApplication ([]) 
form = Form() 
form.show() 
app.exec_() 

回答

0

我很想知道爲什麼還有,它發生在我身上。

對於itemWidget,似乎「底層C/C++對象已被刪除」。多數民衆贊成我反正當我試圖在小部件消失後再次設置ItemWidget(),希望這可以解決它。

我把一個事件時,QTreeWidgetItem降至被調用,但它似乎對象,即會因爲它的下降

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


class InlineEditor (QWidget): 
    _MUTE = 'MUTE' 

    def __init__ (self, parent): 
     QWidget.__init__ (self, parent) 

     self.setAutoFillBackground (True) 
     lo = QHBoxLayout() 
     lo.setSpacing(4) 

     self._cbFoo = QComboBox() 
     for x in ["ABC", "DEF", "GHI", "JKL"]: 
      self._cbFoo.addItem(x) 

     self._leBar = QLineEdit('', self) 
     lo.addWidget (self._cbFoo, 3) 
     lo.addSpacing (5) 
     lo.addWidget (QLabel ('Bar:')) 
     lo.addWidget (self._leBar, 3) 
     lo.addStretch (5) 
     self.setLayout (lo) 

class Tree(QTreeWidget): 
    def __init__(self, parent=None): 
     QTreeWidget.__init__(self, parent) 

     # Here is the issue? 
     self.setDragDropMode(QAbstractItemView.InternalMove) 
     self.installEventFilter(self) 
     self.setColumnCount(3) 

     for n in range (2): 
      i = QTreeWidgetItem (self) # create QTreeWidget the sub i 
      i.setText (0, "first" + str (n)) # set the text of the first 0 
      i.setText (1, "second") 
      for m in range (2): 
       j = QTreeWidgetItem(i) 
       j.setText (0, "child first" + str (m)) 

     #b1 = QCheckBox("push me 0", tree) # this wont work w/ drag by itself either 
     #tree.setItemWidget (tree.topLevelItem(0).child(1), 1, b1) 

     self.item = InlineEditor(self) # deal with a combination of multiple controls 
     self.setItemWidget(self.topLevelItem(0).child(1), 1, self.item) 

    def eventFilter(self, sender, event): 
     if event.type() == QEvent.ChildRemoved: 
      print self.item._cbFoo # looks like this remains 
      print self.item._cbFoo.currentText() # CRASH! but the data is gone 
      #self.setItemWidget(self.topLevelItem(0).child(1), 1, self.item) 
     return False 


class Form (QDialog): 
    def __init__(self,parent=None): 
     QDialog.__init__(self, parent) 

     grid = QGridLayout() 
     tree = Tree() 

     grid.addWidget (tree) 
     self.setLayout (grid) 

app = QApplication ([]) 
form = Form() 
form.show() 
app.exec_() 
2

刪除得到了一個相對的「工作」修復由我自己寫treeDropEvent ...但是如果有人有更優雅的解決方案,請隨時分享。下面的代碼將解決其他人在樹中使用setItemWidgets進行拖放的麻煩,歡呼。

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

class InlineEditor (QWidget): 
    _MUTE = 'MUTE' 

    def __init__ (self, parent): 
     QWidget.__init__ (self, parent) 

     self.setAutoFillBackground (True) 
     lo = QHBoxLayout() 
     lo.setSpacing(4) 

     self._cbFoo = QComboBox() 
     for x in ["ABC", "DEF", "GHI", "JKL"]: 
      self._cbFoo.addItem(x) 

     self._leBar = QLineEdit('', self) 
     lo.addWidget (self._cbFoo, 3) 
     lo.addSpacing (5) 
     lo.addWidget (QLabel ('Bar:')) 
     lo.addWidget (self._leBar, 3) 
     lo.addStretch (5) 
     self.setLayout (lo) 

class Tree(QTreeWidget): 
    def __init__(self, parent=None): 
     QTreeWidget.__init__(self, parent) 

     # Here is the issue? 
     self.setDragDropMode(QAbstractItemView.InternalMove) 
     self.installEventFilter(self) 
     self.setColumnCount(3) 
     self.dropEvent = self.treeDropEvent 

     for n in range (2): 
      i = QTreeWidgetItem (self) # create QTreeWidget the sub i 
      i.setText (0, "first" + str (n)) # set the text of the first 0 
      i.setText (1, "second") 
      for m in range (2): 
       j = QTreeWidgetItem(i) 
       j.setText (0, "child first" + str (m)) 

     self.item = InlineEditor(self) # deal with a combination of multiple controls 
     self.setItemWidget(self.topLevelItem(0).child(1), 1, self.item) 

    def treeDropEvent(self, event): 
     dragItem = self.currentItem() 

     QTreeWidget.dropEvent(self, event) 
     # rebuild widget (grabbing it doesnt seem to work from self.itemWidget?) 
     self.item = InlineEditor(self) 
     self.setItemWidget(dragItem, 1, self.item) 

class Form (QDialog): 
    def __init__(self,parent=None): 
     QDialog.__init__(self, parent) 
    grid = QGridLayout() 
    tree = Tree() 
    grid.addWidget (tree) 
    self.setLayout (grid) 

app = QApplication ([]) 
form = Form() 
form.show() 
app.exec_()