我几乎成功地创建了一个TreeModel来处理多个提供QTreeView的SQL数据库,每个父数据库来自一个单独的数据库。 ItemTree& ItemModel不包含数据,该数据由两个QSqlTableModel和自定义“MAKE DATA'提供。代码,为每个事件创建ItemTree实例,然后为每个事件查找子项并创建这些事件的实例(事件为父项)。这些项目是QModelIndexes。
编辑时,ItemModel的setData正确找到SQL数据的QModelIndex(称为RealIndex),但setData(realIndex,v,role = Qt.EditRole)对所有项都失败。设置setEditStrategy(self.OnFieldChange)将View恢复为其原始数据;使用OnManualSubmit更新视图,但不更新模型。有任何想法吗?问候
#================ EXTERNAL SQL ==============
class Events(QSqlTableModel):
def __init__(self):
QSqlTableModel.__init__(self)
self.setQuery(QSqlQuery("SELECT * FROM m_events"))
self.setEditStrategy(self.OnManualSubmit)
self.select()
events = Events()
eventsIdIndex = events.record().indexOf("id")
eventsUseIndex = events.record().indexOf("use")
class EventChildren(QSqlTableModel):
def __init__(self):
QSqlTableModel.__init__(self)
self.setQuery(QSqlQuery("SELECT * FROM m_event_children"))
self.select()
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:
self.itemParent.itemChildren.append(self)
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):
QAbstractItemModel.__init__(self)
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()
else:
return self.rootItem.columnCount()
def index(self, row, column, parent=QModelIndex()):
if not parent:
return QModelIndex()
if not parent.isValid():
parentItem = self.rootItem
else:
parentItem = parent.internalPointer()
childItem = parentItem.child(row)
if childItem:
return self.createIndex(row, column, childItem)
else:
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()
else:
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)
realModel.submit()
realModel.submitAll()
return True
def flags(self, index):
if not index.isValid():
return 0
else:
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()
view.setModel(eventsModel)
sys.exit(appl.exec_())
答案 0 :(得分:0)
解决。因为QSqlTableModel使用自定义查询,所以没有数据库集。调用setData时,QSqlTableModel无处可写。改为:
self.setTable("talbe_name")
self.select()
写入数据库。这突出了QSqlTableModel的限制,这是setFilter&排序无法解决。将查询拆分为单独的QSqlTableModels&使用Qts其他功能来显示相应的数据,或者,使用自定义QSqlTableModel似乎有一些可能的选项。问候