python qt pyqt pyqt4 qtreeview

python - perezoso cargando artículos para niños Qtreeview



pyqt pyqt4 (2)

Estoy intentando cargar elementos secundarios en una vista de árbol

+top parent1 parent2 parent3

Para comenzar llene el modelo con la información del nodo principal solo y lo adjunte a una vista de árbol, el árbol se ve arriba.

self.mytreeview=QtGui.Qtreeview() self.model=QtGui.QStandardItemModel(self.mytreeview) def initialise_model(self): ''''''Populate the model with parent nodes only'''''' #open file and process each line, each file line has the parent node info .... for file_name_entry in fileobject: parent_item=QtGui.QStandardItem(str(file_name_entry).strip()) parent_item.setData("this is a parent",QtCore.Qt.TooltipRole) self.model.appendRow(parent_item) self.mytreeview.setModel(self.model)

En este punto, ninguno de los padres tiene información de niños. Lo que quiero hacer a continuación es actualizar un nodo padre, cuando el usuario hace clic en el nodo padre (justo a tiempo o cargando la información de un hijo).

Entonces, cuando se hace clic en un nodo padre, y se emite la señal

QtCore.QObject.connect(self.ui.treeView, QtCore.SIGNAL(''clicked(QModelIndex)''), self.update_model)

El código de update_model debe ir a buscar los elementos secundarios de ese elemento primario, actualizar el modelo, actualizar el árbol y expandir el nodo padre.

def update_model(self,index): ''''''Update the model by adding children to selected/clicked parent node only'''''' parent_node=QtGui.QStandardItem(self.model.itemFromIndex(index)) parent_item_index=index.row() #open the file called parent_node.txt and get all the child entries from the file... child_index=0 for child_name_entry in parent_text_fileobject: child_item=QtGui.QStandardItem(str(child_name_entry).strip()) child_item.setData("this is a child",QtCore.Qt.TooltipRole) parent_item.setChild(child_index,child_item) child_index=child_index+1 #Once all the children have been added update the model, by inserting a new row where the parent was self.model.removeRow(parent_item_index)#remove old parent self.model.insertRow(parent_item_index,parent_item)#insert new parent with its children

Cuando intento eliminar el nodo padre seleccionado (el que no tiene hijos) e intento insertar un nuevo elemento padre (con hijos), termina agregando el nuevo padre (con hijos) sobre el nodo padre sin hijos, así que termino con nodos principales duplicados

+top parent1 parent2 +parent2 child_a child_b child_c parent3

Así que solo para recapitular, eliminar e insertar, es decir,

#Once all the children have been added update the model, by inserting a new row where the parent was self.model.removeRow(parent_item_index)#remove old parent self.model.insertRow(parent_item_index,parent_item)#insert new parent with its children

es una mala idea Mirando los comentarios, se ha sugerido que AppendRow () podría ser la respuesta, pero no estoy tan seguro de creer que

self.model.appendRow(parent_item)#new parent with its children

Simplemente agregaría el elemento primario al final de mi modelo y, por lo tanto, el árbol aún tendría nodos principales duplicados, es decir,

+top parent1 **parent2** parent3 **+parent2** child_a child_b child_c

Creo que lo que estoy buscando es una forma de actualizar un nodo existente en el modelo, de modo que el nodo padre seleccionado se pueda actualizar con sus elementos secundarios. p.ej

... self.model.UpdateExisitingNode(node_index) ...

¿Alguna sugerencia sobre cómo actualizar un nodo en el modelo? Tenga en cuenta que estoy usando Windows y PyQt

Saludos


Está duplicando elementos porque está creando otro elemento principal, solo debe crear elementos secundarios nuevos. Por ejemplo:

from PyQt4 import QtGui class Widget(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.mytreeview = QtGui.QTreeView(self) self.setLayout(QtGui.QVBoxLayout()) self.layout().addWidget(self.mytreeview) self.model = QtGui.QStandardItemModel(self.mytreeview) self.mytreeview.setModel(self.model) self.mytreeview.clicked.connect(self.update_model) self.initialise_model() def initialise_model(self): for text in ["parent1", "parent2", "parent3"]: item = QtGui.QStandardItem(text) self.model.appendRow(item) def update_model(self, index): parent = self.model.itemFromIndex(index) for text in ["children1", "children2", "children3"]: children = QtGui.QStandardItem("{}_{}".format(parent.text(), text)) parent.appendRow(children) self.mytreeview.expand(index) if __name__ == ''__main__'': import sys app = QtGui.QApplication(sys.argv) w = Widget() w.show() sys.exit(app.exec_())


Para que esto funcione bien, los elementos principales deben mostrar flechas de expansión antes de que se completen con elementos secundarios. También sería bueno rellenar los elementos de nivel superior cuando se expande por cualquier medio (es decir, a través del mouse, el teclado y también mediante programación), mientras que al mismo tiempo se asegura de que esto solo suceda cuando sea necesario (es decir, solo si el padre está actualmente vacío).

Todo esto se puede lograr simplemente configurando una bandera "Ampliable" en los elementos relevantes y luego reimplementando el método hasChildren de QStandardItemModel . Con eso en su lugar, es muy fácil escribir métodos para llenar los elementos de nivel superior bajo demanda.

Aquí hay una demostración simple basada en su código de ejemplo que implementa todo eso:

import sys from PyQt4 import QtCore, QtGui class StandardItemModel(QtGui.QStandardItemModel): ExpandableRole = QtCore.Qt.UserRole + 500 def hasChildren(self, index): if self.data(index, StandardItemModel.ExpandableRole): return True return super(StandardItemModel, self).hasChildren(index) class Window(QtGui.QWidget): def __init__(self): super(Window, self).__init__() self.mytreeview = QtGui.QTreeView() self.model = StandardItemModel(self.mytreeview) self.mytreeview.setModel(self.model) layout = QtGui.QVBoxLayout(self) layout.addWidget(self.mytreeview) self.mytreeview.expanded.connect(self.update_model) self.initialise_model() def initialise_model(self): self.model.clear() for file_name_entry in fileobject: parent_item = QtGui.QStandardItem(file_name_entry.strip()) parent_item.setData(True, StandardItemModel.ExpandableRole) parent_item.setData("this is a parent", QtCore.Qt.ToolTipRole) self.model.appendRow(parent_item) def update_model(self, index): parent_item = self.model.itemFromIndex(index) if not parent_item.rowCount(): for child_name_entry in parent_text_fileobject: child_item = QtGui.QStandardItem(child_name_entry.strip()) child_item.setData("this is a child", QtCore.Qt.ToolTipRole) parent_item.appendRow(child_item) # dummy test data fileobject = ''parent1 parent2 parent3''.split() parent_text_fileobject = ''child_a child_b child_c''.split() if __name__ == ''__main__'': app = QtGui.QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_())