来自两个SQL数据库的QTreeView - 工作但不更新

时间:2014-07-09 16:42:30

标签: python sql pyqt qtreeview qabstractitemmodel

我几乎成功地创建了一个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_())

1 个答案:

答案 0 :(得分:0)

解决。因为QSqlTableModel使用自定义查询,所以没有数据库集。调用setData时,QSqlTableModel无处可写。改为:

self.setTable("talbe_name")
self.select()

写入数据库。这突出了QSqlTableModel的限制,这是setFilter&排序无法解决。将查询拆分为单独的QSqlTableModels&使用Qts其他功能来显示相应的数据,或者,使用自定义QSqlTableModel似乎有一些可能的选项。问候