2016-08-17 5 views
2

Ich versuche meine Implementierung von QAbstractTableModel zu testen. Ich habe die Methoden rowCount(), columnCount() und data() implementiert.Wie konstruiere ich einen QModelIndex mit gültigem Eltern?

Nach meinem Modell instanziiert wird, egal wie viele Verschachtelungen tief, der übergeordnete Index immer ungültig ist:

parent = model->index(0, 0); 
i = model->index(0, 0, parent); // i.parent().IsValid() == false! 

Jetzt i gültig ist. Aber i.parent() ist nicht. Auch wenn ich weiter Verschachtelung tun:

ancestor = model->index(0, 0); 
parent = model->index(0, 0, ancestor); 
i = model->index(0, 0, parent); // i.parent().IsValid() == false! 

selbst dann, i ist gültig, aber i.parent() nicht.

Ich habe Unit die rowCount und columnCount Methoden getestet und ich habe festgestellt, dass das Modell ein Baummodell ist, das eine Zeile mit, verschachtelt, zwei Zeilen hat. Außerdem ist die Anzahl der Spalten ungleich Null.

Warum ist mein Elternindex immer ungültig?

+0

Sind Sie sicher, dass Sie tatsächlich 'i's Eltern? – Dillydill123

+1

Wenn Sie ein Baummodell erstellen möchten, müssen Sie von 'QAbstractItemModel' und nicht von' QAbstractTableModel' ableiten. – RobbieE

Antwort

4

Es ist ein Tisch. Es sollte kein Baum sein. Aus diesem Grund wird der Elternteil immer ungültig sein. Die QAbstractTableModel::index Implementierung setzt immer ein ungültiges Elternteil, und es soll.

Ihre Erwartungen gelten für ein Baummodell, kein Tabellenmodell. Und sie gelten nur für ein Baummodell, wenn das angegebene Elternelement Kinder hat. Ihr Test geht fälschlicherweise davon aus, dass der Elternteil, den er verwendet, Kinder hat, wenn er keinen hat. Sie können leicht überprüfen, dass: model->hasChildren(parent) wird immer false für eine Tabelle zurückgeben. Der Versuch, einen Index mit einem kinderlosen Elternelement zu erstellen, ist nicht definiert. Idealerweise sollte Ihr Modell darauf bestehen. Somit wäre Ihr Test auch für einen Baum generell falsch.

Wenn Sie einen Baum implementieren möchten, leiten Sie von QAbstractItemModel. Sie werden dann gezwungen sein, bool hasChildren(const QModelIndex& parent) const korrekt zu implementieren - das ist die Methode, die die Strukturansicht (und Ihre Tests!) Verwenden sollten, um zu wissen, ob es zulässig ist, einen Index für das Kind eines bestimmten Elternteils anzufordern.

Im Allgemeinen, wenn model.hasChildren(parent) == false dann sollten Sie nie anrufen model.index(row, col, parent). In der Tat sollte Ihr Modell bestätigen, dass es so ist:

QModelIndex MyModel::index(int row, int col, const QModelIndex & parent) { 
    Q_ASSERT(hasChildren(parent)); 
    Q_ASSERT(row >= 0 && row < rowCount(parent)); 
    Q_ASSERT(col >= 0 && col < columnCount(parent)); 
    void * ptr = ...; // or quintptr ptr = ...; 
    return createIndex(row, col, ptr); 
} 
+0

Warum ist es dann möglich, ein QAbstractTableModel mit einem QTreeView zu verwenden? (z. B. http://stackoverflow.com/questions/27308309/display-data-from-qabstracttablemodel-in-qtreewiew) Funktioniert das nicht auch auf diesen Annahmen? Außerdem hat das Elternteil, das ich verwende, Kinder, ich habe meine Datenmethode so implementiert, dass es funktioniert. Wie schlägst du vor, dass ich vorwärts gehe? Überschreibe ich die :: index Methode? – Diana

+1

Ein 'QTreeView' prüft jeden Elternteil auf Kinder und versucht nur Kindindizes zu erstellen, wenn die Kinder existieren. Eine Baumansicht ist eine vollkommen gültige Methode zum Anzeigen eines Tabellen- oder Listenmodells. Ein Tabellen-/Listenmodell ist ein Baum mit nur einem Stamm. –

+0

# 1. Was ist die genaue Definition von "Kind"? Ich habe die data() -Methode so implementiert, dass sie das parent() inspiziert und Daten zurückgibt. Das ist ein Kind für mich. # 2. Welche Alternative habe ich? Ich kann kein QAbstractTreeModel finden. – Diana

Verwandte Themen