2015-01-10 3 views
3

Это требуется для реализации QAbstractItemModel.parent() метода или иначе получить эту неприятную ошибку:индекса QAbstractItemModel() и родитель() методы

NotImplementedError: QAbstractItemModel.parent() is abstract and must be overridden 

Помимо .parent() метод index() также должен быть переопределен или лицо:

NotImplementedError: QAbstractItemModel.index() is abstract and must be overridden 

ВОПРОС: Какова цель обоих методов и какова разница в том, как они работают?

EDITED СПУСТЯ:

Пример .parent() метод:

def getNodeFromIndex(self, index):  
    if index.isValid(): 
     node = index.internalPointer() 
     if node: 
      return node    
    return self.items 


def parent(self, index): 
    node = self.getNodeFromIndex(index) 
    parentNode = node.getParent() 
    if parentNode == self.items: 
     return QtCore.QModelIndex() 
    return self.createIndex(parentNode.row(), 0, parentNode) 

Пример на .index() метод:

def index(self, row, column, parentIndex): 
    parentNode = self.getNodeFromIndex(parentIndex) 
    childNode = parentNode.getChildren(row) 
    if childNode:    
     newIndex=self.createIndex(row, column, childNode) 
     return newIndex 
    else: 
     return QtCore.QModelIndex() 

От бесконечных испытаний я вижу, что .parent() метод вызывается только на верхнем уровне QTableView элементов. Хотя .index() вызывается для всех элементов: элементов верхнего уровня, второго уровня, элементов grand-children третьего уровня и т. Д. Я также вижу, что оба возвращают QModelIndex с переменной строки, столбца и данных «связаны», к нему. Похоже, что QModelIndexes, возвращенные обоими методами, должны быть синхронизированы.

.parent() возвращает родительский элемент модели с заданным индексом. Если элемент не имеет родителя, возвращается недопустимый QModelIndex. Общее соглашение, используемое в моделях, которые раскрывают структуры древовидных данных, состоит в том, что только элементы в первом столбце имеют дочерние элементы. В этом случае при повторной реализации этой функции в подклассе столбец возвращаемого значения QModelIndex будет равен 0. При переопределении этой функции в подклассе будьте осторожны, чтобы не вызывать функции-члены QModelIndex, например QModelIndex::parent(), поскольку индексы, принадлежащие вашей модели, будут просто вызовите вашу реализацию, приводящую к бесконечной рекурсии.

.index() возвращает индекс элемента в модели, заданной данным строкой, столбцом и родительским индексом. При переопределении этой функции в подклассе вызовите createIndex(), чтобы генерировать индексы моделей, которые другие компоненты могут использовать для ссылки на элементы в вашей модели.

Следует упомянуть, что оба метода используют метод self.createIndex(row, column, dataVariable). Поэтому они оба делают то же самое: они создают QModelIndexes. Я просто не понимаю, почему нам нужны два метода, чтобы сделать то же самое! И трудно отлаживать его, так как кажется, что они работают в бесконечном цикле ....

+1

Что мешает вам прочитать [Qt документацию по этому вопросу] (https://qt-project.org/doc/qt-4.8/model-view-programming.html#parents-and-children)? – ekhumoro

+0

Привет, Эхуморо! Примеры Qt docs в основном представлены в C (по крайней мере, в его учебнике по MVC). – alphanumeric

+0

Из бесконечного тестирования я вижу, что метод '.parent()' вызывается только на элементах QTableView верхнего уровня. В то время как '.index()' вызывается для всех элементов: элементы верхнего уровня, второго уровня, элементы грандиозных детей третьего уровня и т. Д. Я также вижу, что оба возвращают QModelIndex с переменной строки, столбца и данных " связанный "с ним. Похоже, что QModelIndexes, возвращенные обоими методами, должны быть синхронизированы. – alphanumeric

ответ

3

Эти методы определены аббревиатурой, чтобы заставить пользователя реализовать их при подклассификации. Ваша модель не будет работать без их реализации, потому что они необходимы для определения структуры вашей модели.

Обычно, когда вы хотите создать иерархическую модель, вы должны реализовать методы index() и parent(). Для моделей таблиц и списков во многих случаях этого достаточно для подкласса QAbstractListModel и QAbstractTableModel, которые имеют стандартные реализации этих двух методов.

Простыми словами QAbstractItemModel.parent() возвращает родительский QModelIndex от ребенка и QAbstractItemModel.index() вызывается всякий раз, когда модель или представление должно создать QModelIndex для конкретного дочернего элемента (или элемента верхнего уровня, если родитель является инвалидом QModelIndex).

+0

Спасибо! Я пытаюсь разработать модель для расширения для QTreeView, если возникнет такая необходимость. – alphanumeric

+0

Можно ли сказать, что методы '.parent()' используются для «создания» QModelIndex для элементов верхнего уровня. А методы '.index()' используются для создания QModelIndex для любого другого элемента верхнего уровня? Или такое заявление было бы неправильным? – alphanumeric

+0

@Sputnix Нет, это совершенно неправильно. 'index()' фактически используется для создания 'QModelIndex' каждого элемента в модели. Это может быть элемент верхнего уровня или дочерний элемент. 'parent()' используется для возврата родителя любого элемента. В иерархических моделях многие элементы на разных уровнях имеют родителей, и только элементы верхнего уровня не имеют родителя, в котором для них необходимо вернуть недопустимый 'QModelIndex' в' parent() '. – Nejat

Смежные вопросы