2010-11-07 9 views
6

Sto usando PyQt per gestire una vista ad albero usando un QAbstractItemModel. Finora l'ho implementato con successo in modo tale da poter caricare i dati, espanderlo e comprimerlo e modificare i valori.pyqt: Cercando di capire gli inserimenti per QAbstractDataModel e QTreeView

Una cosa che non sono in grado di fare, tuttavia, è avvolgere la mia mente nell'inserimento e nella rimozione delle righe.

Versione corta di quello che sto cercando di fare:

Quando l'utente modifica una cella particolare, ho bisogno di eliminare effettivamente l'elemento di fondo nella mia gerarchia di oggetti e sostituirlo con uno diverso. Lo implemento nel metodo setData del mio modello. Dal momento che non capisco completamente quello che sto facendo, mi sembra di averlo impostato in modo che diventi segreto.

Fondamentalmente, ho solo bisogno di capire meglio come il modello di dati interagisce con QModelIndex, ma leggere e rileggere i documenti non sembra illuminarmi. Qualsiasi aiuto (o qualsiasi link a un tutorial decente - preferibilmente, anche se non necessariamente, in python - sarebbe molto apprezzato).

Ecco un esempio del codice che sto usando:

#--------------------------------------------------------------------------- 
def setData(self, index, value, role=QtCore.Qt.EditRole): 
    """ 
    Sets the data. 
    """ 
    if index.isValid() and (0 <= index.row() < self.rowCount()): 

     item = index.internalPointer() 
     value = value.toString() 
     if index.column() == 5: 
      # rip out the current object and replace it with a new one of 
      # the correct datatype. 

      #next 4 lines get info from my underlying hierarchy of objects 
      dataType = str(value) 
      parent = item.get_parent() 
      name = item.get_name() 
      row = parent.get_row_of_child(name) 

      #assuming everything is ok, I now am trying to manage the 
      #underlying objects 
      if row != None: 

       #I am calling this because I think I need to, but don't 
       #really know if it is called for here or not 
       self.beginInsertRows(self.parent(index), row, 1) 

       #Next 3 lines create and initialize a new underlying 
       #object that will be inserted. 
       newItem = self.root.create_template_param_obj(dataType, 
                   name, 
                   parent) 
       newItem.set_index(row) 
       newItem.set_default_value(item.get_default_value()) 

       #now I remove the old object from my underlying 
       #hierarchy and insert the new one 
       parent.remove_child_at_row(row) 
       parent.insert_child_at_row(newItem, row) 

       #this is where I get lost. I *think* I need to point to 
       #the new underlying object (i.e. rebuild the index) 
       #so I am going to call the data model's index method. 
       #But that needs the index of the parent, so first I 
       #call the data model's parent method to get the index 
       #of the parent. But this code segfaults (I think it 
       #is the treeview that actually freaks out because this 
       #setData method completes properly before the whole thing 
       #crashes. Does anyone have a pointer to a decent tutorial 
       #that will explain how data models and mode indexes work? 
       self.index(row, 5, self.parent(index)) 
       self.endInsertRows() 

     self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), 
           index, index) 
     return True 

    #Ignore any role other than the edit role 
    return False 

#--------------------------------------------------------------------------- 
def index(self, row, column, parent): 
    """ 
    Connect the data model to the actual object hierarchy. 
    """ 
    if not self.hasIndex(row, column, parent): 
     return QtCore.QModelIndex() 

    if not parent.isValid(): 
     parentItem = self.root 
    else: 
     parentItem = parent.internalPointer() 

    childItem = parentItem.get_child_at_row(row) 
    if childItem: 
     return self.createIndex(row, column, childItem) 
    else: 
     return QtCore.QModelIndex() 


#--------------------------------------------------------------------------- 
def parent(self, index): 
    """ 
    Returns a QModelIndex of the parent 
    """ 
    if not index.isValid(): 
     return QtCore.QModelIndex() 

    childItem = index.internalPointer() 
    if not childItem: 
     return QtCore.QModelIndex() 

    parentItem = childItem.get_parent() 

    if parentItem == self.root: 
     return QtCore.QModelIndex() 

    return self.createIndex(parentItem.get_index(), 0, parentItem) 

risposta

2

cercherò di darvi alcuni consigli, mi ricordo che questa parte ha fatto la mia testa come bene quando ho avuto per la sua attuazione per la mia applicazione !

Quindi, da quello che mi ricordo, è necessario implementare i seguenti metodi virtuali:

virtual bool insertRows(int Row, int Count, const QModelIndex& rParent); 
virtual bool removeRows(int Row, int Count, const QModelIndex& rParent = QModelIndex()); 

bool SuperModel::insertRows(int Row, int Count, const QModelIndex& rParent) 
{ 
... 
    // On débute l'insertion des lignes. 
    beginInsertRows(rParent, Row, Row + Count -1); 
    // ... Perform insertion here, you'll have something like 
    pParent->addChild(Row); 
    endInsertRows(); 
} 

bool SuperModel::removeRows(int Row, int Count, const QModelIndex& rParent) 
{ 
    ... 
    beginRemoveRows(rParent, Row, Row + Count -1); 
    // ... Perform removing here, you'll have something like 
    pParent->removeChild(Row); 
    endRemoveRows(); 
} 

Alcune altre informazioni: http://doc.qt.io/archives/qt-4.7/qabstractitemmodel.html#insertRows

spero che vi aiuterà un po '... non è in PyQt, ma spero che vi darà alcuni suggerimenti ...

+0

Andy, era così. Grazie. Con il tuo aiuto ero persino in grado di farlo funzionare senza i due metodi. Avevo solo bisogno di chiamare: self.beginRemoveRows (self.parent (index), row, row) prima di rimuovere la riga e self.endRemoveRows() dopo. Lo stesso con l'inserimento del nuovo oggetto. Sembra così ovvio ora ma non riuscivo a capirlo senza il tuo aiuto. Grazie ancora! – bvz

+0

Wicked! Bel lavoro! –