QTreeView From Two SQL Databases - Working, But Not Updating

Wednesday, July 9, 2014

I've virtually successfully created a TreeModel to handle multiple SQL databases feeding a QTreeView, with each parent being from a separate database. ItemTree & ItemModel contain no data, which is supplied by two QSqlTableModel's and custom 'MAKE DATA' code, creating ItemTree instances per event, then finding the children for each event and making instances of those (with the event as parent). The items are QModelIndexes.

When editing, the ItemModel's setData correctly finds the SQL data's QModelIndex (called RealIndex), but setData(realIndex, v, role=Qt.EditRole) fails for all items. Setting setEditStrategy(self.OnFieldChange) reverts the View to its original data; using OnManualSubmit updates the view, but not the model. Any ideas? Regards

#================ EXTERNAL SQL ==============
class Events(QSqlTableModel):
def __init__(self):

self.setQuery(QSqlQuery("SELECT * FROM m_events"))

events = Events()
eventsIdIndex = events.record().indexOf("id")
eventsUseIndex = events.record().indexOf("use")

class EventChildren(QSqlTableModel):
def __init__(self):

self.setQuery(QSqlQuery("SELECT * FROM m_event_children"))

self.childEventIndex = self.fieldIndex("event")
self.childEventQi = self.createIndex(0, self.childEventIndex)
self.childEventOccurrences = 1

children = EventChildren()
childrenIdIndex = children.record().indexOf("id")
childrenEventIndex = children.record().indexOf("event")
childrenEventQi = children.createIndex(0, childrenEventIndex)
childrenDescIndex = children.record().indexOf("desc")

#========== INTERNAL DATA ==========
#----- TREE ITEMS -----
class ItemTree():
def __init__(self, data=[], parent=None):

self.itemData = data # the data for each row, as a list of QModelIndexes from the SQL
self.itemParent = parent
self.itemChildren = []

if parent:

def child(self, row):
return self.itemChildren[row]

def childCount(self):
return len(self.itemChildren)

def row(self):
if self.itemParent:
return self.itemParent.itemChildren.index(self)
return False

def columnCount(self):
return len(self.itemData)

def data(self, index, role=Qt.DisplayRole):
return self.itemData[index]

def parent(self):
return self.itemParent

#----- VIEWS MODEL -----
class ItemModel(QAbstractItemModel):
def __init__(self, rootItem=None, parent=None):

self.rootItem = rootItem

def rowCount(self, parent=QModelIndex()):
if parent.column() > 0:
return 0

if not parent.isValid():
parentItem = self.rootItem

else: parentItem = parent.internalPointer()

return parentItem.childCount()

def columnCount(self, parent):
if parent.isValid():
return parent.internalPointer().columnCount()
return self.rootItem.columnCount()

def index(self, row, column, parent=QModelIndex()):
if not parent:
return QModelIndex()

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

childItem = parentItem.child(row)
if childItem:
return self.createIndex(row, column, childItem)
return QModelIndex()

def parent(self, index=QModelIndex()):
if not index.isValid():
return QModelIndex()

parentItem = index.internalPointer().parent()

if parentItem == self.rootItem:
return QModelIndex()

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

def data(self, index, role=Qt.DisplayRole):
if not index.isValid():
return QVariant()
if role == Qt.DisplayRole or role == Qt.EditRole:
col = index.column()
return index.internalPointer().itemData[col].data().toString()
return QVariant()

def setData(self, index, v, role=Qt.EditRole):
if role == Qt.EditRole:
realIndex = index.internalPointer().data(index.column())
realModel = realIndex.model()

print v.toString()
print realIndex.row()
print realIndex.column()
print realIndex.model()
realModel.setData(realIndex, v, role=Qt.Qt.EditRole)

return True

def flags(self, index):
if not index.isValid():
return 0
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable

def headerData(self, section, orientation, role=Qt.DisplayRole):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self.rootItem.data(section)
return QVariant()

#===== MAKE DATA =====
eventsRootItem = ItemTree(data=["ID","Use"])

tempEvents = []; finalEvents = []
for e in range(events.rowCount()):
id = str(events.record(e).value(eventsIdIndex).toString()); tempEvents.append("event"+id); finalEvents.append("event"+id)
idQi = events.createIndex(e, eventsIdIndex, events)
useQi = events.createIndex(e, eventsUseIndex, events)

for i in range(len(tempEvents)):
tempEvents[i] = ItemTree(data=[idQi, useQi], parent=eventsRootItem)
finalEvents[i] = tempEvents[i]
del tempEvents[0]

for e in eventsRootItem.itemChildren:
eventId = e.itemData[0].data().toString() # 0 here relates to the first item in the event data, which is the events id index
eventsChildrenEventIds = children.match(childrenEventQi, Qt.DisplayRole, eventId, -1)
for c in eventsChildrenEventIds:
row = c.row()
idQi = children.createIndex(row, childrenIdIndex, children)
eventQi = children.createIndex(row, childrenEventIndex, children)
descQi = children.createIndex(row, childrenDescIndex, children)
t = ItemTree(data=[idQi, descQi], parent=e)

#----- RUN -----
eventsModel = ItemModel(rootItem=eventsRootItem)
view = QTreeView()