2010-03-04 13 views
1

J'essaie de garder un widget mis en QTreeWidgetItem après une Reparent (glisser-déposer) en utilisant QTreeWidget.setItemWidget()PyQt QTreeWidget setItemWidget dissapears après glisser/déposer

Mais le résultat, si vous compilez les éléments suivants code - est que le widget à l'intérieur du QTreeWidgetItem disparaît. Une idée pourquoi? Quel est le code fixerait ce (repeupler le QTreeWidgetItem avec le widget Je suppose?)

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

Répondre

0

J'aimerais savoir pourquoi aussi bien, cela arrive à moi aussi.

Il semble que "l'objet C/C++ sous-jacent a été supprimé" pour itemWidget. C'est ce que j'obtiens de toute façon quand j'essaie de mettre à nouveau SetItemWidget() après que le widget disparaisse dans l'espoir que cela le corrige.

je mets un événement pour s'appeler lorsque l'QTreeWidgetItem est abandonné, mais il semble que l'objet est supprimé dès qu'il est tombé

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

a réussi à obtenir une solution relativement « travailler » dans en écrivant mon propre treeDropEvent ... cependant si quelqu'un a une solution plus élégante, n'hésitez pas à partager. Le code ci-dessous va résoudre les maux de tête de quelqu'un d'autre pour faire glisser/déposer avec setItemWidgets dans un arbre, acclamations.

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