2010-11-07 4 views
6

Estoy usando PyQt para administrar una vista en árbol usando un QAbstractItemModel. Hasta ahora lo he implementado con éxito de manera que pueda cargar los datos, expandirlos y contraerlos, y editar valores.pyqt: Tratando de comprender insertrows para QAbstractDataModel y QTreeView

Una cosa que no soy capaz de hacer, sin embargo, es rodear mi cabeza al insertar y eliminar filas.

Versión corta de lo que estoy tratando de hacer:

Cuando el usuario edita una celda en particular, tengo que eliminar realmente el elemento subyacente en mi jerarquía de objetos y sustituirlo por uno diferente. Implemento esto en el método setData de mi modelo. Como no entiendo completamente lo que estoy haciendo, parece que lo configuré para que fallara.

Básicamente, solo necesito obtener una mejor comprensión de cómo el modelo de datos interactúa con QModelIndex, pero leer y volver a leer los documentos no parece iluminarme. Cualquier ayuda (o cualquier enlace a un tutorial decente, preferiblemente, aunque no necesariamente, en python) también sería muy apreciada).

Este es un ejemplo del código que estoy utilizando:

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

Respuesta

2

Voy a tratar de darle algunos consejos, recuerdo que esta parte lo hizo en mi cabeza, así que tuve que ponerlo en práctica para mi aplicación !

Por lo tanto, de lo que recuerdo, usted tiene que poner en práctica los siguientes métodos virtuales:

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(); 
} 

Algunos más informaciones: http://doc.qt.io/archives/qt-4.7/qabstractitemmodel.html#insertRows

espero que le ayudará un poco ... no es en PyQt pero con suerte le dará algunos consejos ...

+0

Andy, eso fue todo. Gracias. Con su ayuda, incluso pude hacer que funcionara sin los dos métodos. Solo necesitaba llamar: self.beginRemoveRows (self.parent (index), row, row) antes de eliminar la fila, y self.endRemoveRows() después. Lo mismo con insertar el nuevo objeto. Parece tan obvio ahora, pero no podría resolverlo sin su ayuda. ¡Gracias de nuevo! – bvz

+0

¡Malvado! ¡Buen trabajo! –

Cuestiones relacionadas