Model View Tutorial Part2/de

From Qt Wiki
Jump to navigation Jump to search
This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

←Teil 1: Table Modell
↑Übersicht Model/View Tutorial:CD Verwaltung↑
Teil 2: Delegate und View→

Ein Modell, dessen Werte editiert werden können

Damit Werte in einem Modell editiert werden können, muss die Methode flags(…) überschrieben werden und für alle editierbaren Zellen auch das flag Qt::ItemIsEditable zurückliefern. Außerdem muss die Methode setData überschrieben werden, da diese von der View aufgerufen wird, um Werte in das Modell zu schreiben.

Wenn die Methode setData() überschrieben wird, muss nach dem Ändern der Werte das Signal dataChanged() explizit ausgelöst werden. Bleibt das Signal aus, dann fehlt den mit dem Modell verbundenen Views der Impuls, ihren Zustand aktualisieren.

Es sind also diese beiden virtuellen Funktionen zu überschreiben:

  • Qt::ItemFlags flags(const QModelIndex& index ) const
  • bool setData(const QModelIndex& index, const QVariant& value, int role)

Im folgenden wird deren Implementierungen beschrieben

flags

Die Methode flags() [doc.qt.nokia.com] wird benutzt, wenn man Eigenschaften eines Modell-Elements ändern möchte. Die am häufigsten benötigten sind:

Wert Beschreibung
Qt::ItemIsSelectable Das Element kann selektiert werden (Standard).
Qt::ItemIsEditable Das Element kann editiert werden.
Qt::ItemIsUserCheckable Das Element kann (üblicherweise mittels einer Checkbox) angekreuzt werden.
Qt::ItemIsEnabled Der Benutzer kann mit dem Element interagieren (Standard).

Wird für ein Element Qt::ItemIsUserCheckable zurückgegeben, wird bei setData auch die Rolle Qt::CheckStateRole übergeben.

In unserem einfachen Beispiel kann jedes Element editiert werden:

  1. Qt::ItemFlags CdModel::flags(const QModelIndex& index ) const
  2. {
  3.     if(index.isValid())
  4.         return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
  5.  
  6.     return QAbstractItemModel::flags(index);
  7. }

setData

Die Methode setData [doc.qt.nokia.com] wird von der View (bzw. eigentlich dem Delegate, siehe später) aufgerufen, um die Werte zu setzen. Es können all die Werte gesetzt werden, die mittels data() auch gelesen werden können. Als erstes müssen die Übergabeparameter validiert (= auf ihre Gültigkeit geprüft werden) werden. Dann muss die Rolle überprüft und die Werte im Datenmodell geändert werden. Abschließend muss das Signal dataChanged ausgelöst werden. Wird das vergessen, wird die Datenänderung nicht in der View angezeigt.

Sollte ein Editiervorgang nicht klappen, muss die Methode false zurückliefern, ansonsten true.

In unserem einfachen Beispiel verwenden wir die folgende Implementierung:

  1. bool CdModel::setData(const QModelIndex& index, const QVariant& value, int role)
  2. {
  3.     // validate the index and that row and column are inside the given borders...
  4.     if(!index.isValid() || (m_data.size() <= index.row()) || (columnCount() <= index.column()))
  5.         return false;
  6.  
  7.     if(Qt::EditRole == role)
  8.     {
  9.         // change the value of the model
  10.         CdDisk disk = m_data.at(index.row());
  11.         switch(index.column())
  12.         {
  13.         case 0:
  14.             disk.m_title = value.toString();
  15.             break;
  16.         case 1:
  17.             disk.m_author = value.toString();
  18.             break;
  19.         case 2:
  20.             disk.m_genre = value.toString();
  21.             break;
  22.         case 3:
  23.             disk.m_year = value.toInt();
  24.             break;
  25.         }
  26.         m_data.changeDisk(index.row(), disk);
  27.  
  28.         // don't forget to emit the signal dataChanged and to return true
  29.         emit dataChanged(index, index);
  30.         return true;
  31.     }
  32.  
  33.     // in case, no editing was done, return false.
  34.     return false;
  35. }

Zum Editieren muss auch die Methode data() modifiziert werden:

  1. QVariant CdModel::data(const QModelIndex &index, int role) const
  2. {
  3.     if(!index.isValid())
  4.         return QVariant();
  5.  
  6.     if((Qt::DisplayRole == role) || (Qt::EditRole == role))
  7.     {
  8.         ...
  9.     }
  10.  
  11.     return QVariant();
  12. }