Model View Tutorial Part2/de: Difference between revisions
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
<div class="factbox right"> | |||
===Table of Content=== | |||
* [[#6cf652940458d1314e876f9344973bb6|Ein Modell, dessen Werte editiert werden können]] | |||
** [[#4e5868d676cb634aa75b125a0f741abf|flags]] | |||
** [[#8feaa50ca223fd78d6e50b2649d94ddc|setData]] | |||
</div> | |||
[http://qt.io/groups/qt_german/wiki/Model-View-Tutorial-Teil1 ←Teil 1: Table Modell]<br />[http://qt.io/groups/qt_german/wiki/Model_View_Tutorial ↑Übersicht Model/View Tutorial:CD Verwaltung↑]<br />[http://qt.io/groups/qt_german/wiki/Model-View-Tutorial-Teil2-Delegate-und-View 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 [http://qt.io/groups/qt_german/wiki/virtuellen-Funktionen 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 [http://doc.qt.nokia.com/latest/qabstractitemmodel.html#flags flags()] ''[doc.qt.nokia.com]'' wird benutzt, wenn man Eigenschaften eines Modell-Elements ändern möchte. Die am häufigsten benötigten sind: | |||
{| class="infotable line" | |||
| '''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: | |||
<div class="cpp-qt geshi"> | |||
# <div class="de1">[http://doc.qt.io/Qt.html <span class="kw5">Qt</span>]<span class="sy0">::</span><span class="me2">ItemFlags</span> CdModel<span class="sy0">::</span><span class="me2">flags</span><span class="br0">(</span><span class="kw4">const</span> [http://doc.qt.io/QModelIndex.html <span class="kw5">QModelIndex</span>]<span class="sy0">&</span> index <span class="br0">)</span> <span class="kw4">const</span></div> | |||
# <div class="de1"><span class="br0">{</span></div> | |||
# <div class="de1"> <span class="kw1">if</span><span class="br0">(</span>index.<span class="me1">isValid</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span></div> | |||
# <div class="de1"> <span class="kw1">return</span> [http://doc.qt.io/Qt.html <span class="kw5">Qt</span>]<span class="sy0">::</span><span class="me2">ItemIsEnabled</span> <span class="sy0">|</span> [http://doc.qt.io/Qt.html <span class="kw5">Qt</span>]<span class="sy0">::</span><span class="me2">ItemIsSelectable</span> <span class="sy0">|</span> [http://doc.qt.io/Qt.html <span class="kw5">Qt</span>]<span class="sy0">::</span><span class="me2">ItemIsEditable</span><span class="sy0">;</span></div> | |||
# <div class="de2"> </div> | |||
# <div class="de1"> <span class="kw1">return</span> [http://doc.qt.io/QAbstractItemModel.html <span class="kw5">QAbstractItemModel</span>]<span class="sy0">::</span><span class="me2">flags</span><span class="br0">(</span>index<span class="br0">)</span><span class="sy0">;</span></div> | |||
# <div class="de1"><span class="br0">}</span></div> | |||
</div> | |||
==setData== | |||
Die Methode [http://doc.qt.nokia.com/latest/qabstractitemmodel.html#setData 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: | |||
<div class="cpp-qt geshi"> | |||
# <div class="de1"><span class="kw4">bool</span> CdModel<span class="sy0">::</span><span class="me2">setData</span><span class="br0">(</span><span class="kw4">const</span> [http://doc.qt.io/QModelIndex.html <span class="kw5">QModelIndex</span>]<span class="sy0">&</span> index<span class="sy0">,</span> <span class="kw4">const</span> [http://doc.qt.io/QVariant.html <span class="kw5">QVariant</span>]<span class="sy0">&</span> value<span class="sy0">,</span> <span class="kw4">int</span> role<span class="br0">)</span></div> | |||
# <div class="de1"><span class="br0">{</span></div> | |||
# <div class="de1"> <span class="co1">// validate the index and that row and column are inside the given borders...</span></div> | |||
# <div class="de1"> <span class="kw1">if</span><span class="br0">(</span><span class="sy0">!</span>index.<span class="me1">isValid</span><span class="br0">(</span><span class="br0">)</span> <span class="sy0">||</span> <span class="br0">(</span>m_data.<span class="me1">size</span><span class="br0">(</span><span class="br0">)</span> <span class="sy0"><=</span> index.<span class="me1">row</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="sy0">||</span> <span class="br0">(</span>columnCount<span class="br0">(</span><span class="br0">)</span> <span class="sy0"><=</span> index.<span class="me1">column</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span><span class="br0">)</span></div> | |||
# <div class="de2"> <span class="kw1">return</span> false<span class="sy0">;</span></div> | |||
# <div class="de1"> </div> | |||
# <div class="de1"> <span class="kw1">if</span><span class="br0">(</span>[http://doc.qt.io/Qt.html <span class="kw5">Qt</span>]<span class="sy0">::</span><span class="me2">EditRole</span> <span class="sy0">==</span> role<span class="br0">)</span></div> | |||
# <div class="de1"> <span class="br0">{</span></div> | |||
# <div class="de1"> <span class="co1">// change the value of the model</span></div> | |||
# <div class="de2"> CdDisk disk <span class="sy0">=</span> m_data.<span class="me1">at</span><span class="br0">(</span>index.<span class="me1">row</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span></div> | |||
# <div class="de1"> <span class="kw1">switch</span><span class="br0">(</span>index.<span class="me1">column</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span></div> | |||
# <div class="de1"> <span class="br0">{</span></div> | |||
# <div class="de1"> <span class="kw1">case</span> <span class="nu0">0</span><span class="sy0">:</span></div> | |||
# <div class="de1"> disk.<span class="me1">m_title</span> <span class="sy0">=</span> value.<span class="me1">toString</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></div> | |||
# <div class="de2"> break<span class="sy0">;</span></div> | |||
# <div class="de1"> <span class="kw1">case</span> <span class="nu0">1</span><span class="sy0">:</span></div> | |||
# <div class="de1"> disk.<span class="me1">m_author</span> <span class="sy0">=</span> value.<span class="me1">toString</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></div> | |||
# <div class="de1"> break<span class="sy0">;</span></div> | |||
# <div class="de1"> <span class="kw1">case</span> <span class="nu0">2</span><span class="sy0">:</span></div> | |||
# <div class="de2"> disk.<span class="me1">m_genre</span> <span class="sy0">=</span> value.<span class="me1">toString</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></div> | |||
# <div class="de1"> break<span class="sy0">;</span></div> | |||
# <div class="de1"> <span class="kw1">case</span> <span class="nu0">3</span><span class="sy0">:</span></div> | |||
# <div class="de1"> disk.<span class="me1">m_year</span> <span class="sy0">=</span> value.<span class="me1">toInt</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></div> | |||
# <div class="de1"> break<span class="sy0">;</span></div> | |||
# <div class="de2"> <span class="br0">}</span></div> | |||
# <div class="de1"> m_data.<span class="me1">changeDisk</span><span class="br0">(</span>index.<span class="me1">row</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">,</span> disk<span class="br0">)</span><span class="sy0">;</span></div> | |||
# <div class="de1"> </div> | |||
# <div class="de1"> <span class="co1">// don't forget to emit the signal dataChanged and to return true</span></div> | |||
# <div class="de1"> emit dataChanged<span class="br0">(</span>index<span class="sy0">,</span> index<span class="br0">)</span><span class="sy0">;</span></div> | |||
# <div class="de2"> <span class="kw1">return</span> true<span class="sy0">;</span></div> | |||
# <div class="de1"> <span class="br0">}</span></div> | |||
# <div class="de1"> </div> | |||
# <div class="de1"> <span class="co1">// in case, no editing was done, return false.</span></div> | |||
# <div class="de1"> <span class="kw1">return</span> false<span class="sy0">;</span></div> | |||
# <div class="de2"><span class="br0">}</span></div> | |||
</div> | |||
Zum Editieren muss auch die Methode '''data()''' modifiziert werden: | |||
<div class="cpp-qt geshi"> | |||
# <div class="de1">[http://doc.qt.io/QVariant.html <span class="kw5">QVariant</span>] CdModel<span class="sy0">::</span><span class="me2">data</span><span class="br0">(</span><span class="kw4">const</span> [http://doc.qt.io/QModelIndex.html <span class="kw5">QModelIndex</span>] <span class="sy0">&</span>index<span class="sy0">,</span> <span class="kw4">int</span> role<span class="br0">)</span> <span class="kw4">const</span></div> | |||
# <div class="de1"><span class="br0">{</span></div> | |||
# <div class="de1"> <span class="kw1">if</span><span class="br0">(</span><span class="sy0">!</span>index.<span class="me1">isValid</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span></div> | |||
# <div class="de1"> <span class="kw1">return</span> [http://doc.qt.io/QVariant.html <span class="kw5">QVariant</span>]<span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></div> | |||
# <div class="de2"> </div> | |||
# <div class="de1"> <span class="kw1">if</span><span class="br0">(</span><span class="br0">(</span>[http://doc.qt.io/Qt.html <span class="kw5">Qt</span>]<span class="sy0">::</span><span class="me2">DisplayRole</span> <span class="sy0">==</span> role<span class="br0">)</span> <span class="sy0">||</span> <span class="br0">(</span>[http://doc.qt.io/Qt.html <span class="kw5">Qt</span>]<span class="sy0">::</span><span class="me2">EditRole</span> <span class="sy0">==</span> role<span class="br0">)</span><span class="br0">)</span></div> | |||
# <div class="de1"> <span class="br0">{</span></div> | |||
# <div class="de1"> ...</div> | |||
# <div class="de1"> <span class="br0">}</span></div> | |||
# <div class="de2"> </div> | |||
# <div class="de1"> <span class="kw1">return</span> [http://doc.qt.io/QVariant.html <span class="kw5">QVariant</span>]<span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span></div> | |||
# <div class="de1"><span class="br0">}</span></div> | |||
</div> |
Revision as of 13:56, 25 February 2015
Table of Content
←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:
- {
- if(index.isValid())
- }
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:
- {
- // validate the index and that row and column are inside the given borders...
- if(!index.isValid() || (m_data.size() <= index.row()) || (columnCount() <= index.column()))
- return false;
- {
- // change the value of the model
- CdDisk disk = m_data.at(index.row());
- switch(index.column())
- {
- case 0:
- disk.m_title = value.toString();
- break;
- case 1:
- disk.m_author = value.toString();
- break;
- case 2:
- disk.m_genre = value.toString();
- break;
- case 3:
- disk.m_year = value.toInt();
- break;
- }
- m_data.changeDisk(index.row(), disk);
- // don't forget to emit the signal dataChanged and to return true
- emit dataChanged(index, index);
- return true;
- }
- // in case, no editing was done, return false.
- return false;
- }
Zum Editieren muss auch die Methode data() modifiziert werden: