[Solved] QSqlTableModel und Drag'n'Drop
-
Eigeninitiative ?!? API ?!?
QStringList QStringListModel::stringList () const
Schau das abgeleitete QStringListModel an, verpass dem intern ein private member
int m_maxPlatz;
Initialisier den im Konstruktor auf -1. Spendier dem ganzen ne public Methodevoid setMaxPlatz(int wieviele=-1) { if (wieviele == -1 || (wieviele > 0 && wieviele > view.strinList().size())) m_maxPlatz=wieviele; }
und überprüf imdropMimeTarget(...)
ob die derzeite stringlistengröße+1 größer m_maxPlatz wird, wenn ja, returniere false ... wenn m_maxPlatz == -1 dann sparste dir die Überprüfung da dann unbegrenzt platz is ...
-
Vielen Dank erstmal, ich hab nun heftig hin und her probiert. Der Weg ist soweit klar aber mit diesem Teil
padreigh schrieb:
...0 && wieviele > view.strinList().size())) ...
hab ich meine schwierigkeiten .... Mir ist nicht so ganz klar wie ich darauf zugreifen soll, ohne dabei etwas zu benutzen, was verhindern würde das ich das ganze an andere stelle einfach wiederverwenden könnte .... kannst du mir da bitte nochmal auf die Sprünge helfen ?
-
Nach ein wenig Trial&Error bin ich nun fast da angelangt wo ich hinwollte. Welche Optionen auf der Dropseite sind, diese Auszulesen etc. funktioniert. Auch das die Dropseite nur eine Anzahl X optionen akzeptiert funktioniert. Nur hab ich nun noch 1 Problem, wenn ich die Anzahl der Maximalen Plätze auf der Dropseite erreicht habe, kann ich auch nicht mehr zurückschieben.
Mit diesem Code wird ja nachgeschaut, an welche Stelle der "Drop" eingefügt wird.
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { if (action == Qt::IgnoreAction) return true; if (!data->hasFormat("application/vnd.text.list")) return false; if (column > 0) return false; int beginRow; if (row != -1) { beginRow = row; } else if (parent.isValid()) { beginRow = parent.row(); } else { beginRow = rowCount(QModelIndex()); }
Kann ich irgendwie mit einem vergleich oder ähnlichem Feststellen, auf welche Stringliste da gerade geprüft wird ? Das ist mir im moment noch ein kleines Rätsel ....
-
Dann hast du warscheinlich was anders gemacht als ich vorgeschlagen hab ... zB die Anzahl hardgecoded? Sonst wäre es einfach in der einen QStringListModelKlasse lässt du m_maxPlatz auf -1 (== unbegrenzt), in der anderen wo es beschränkt ist, beschränkst du es halt ...
ich meinte sowas:
#ifndef WIDGET_H #define WIDGET_H #include <QStringListModel> #include <QMimeData> /* alle unrelevanten Stellen entFERNT */ class DragDropStringListModel : public QStringListModel { Q_OBJECT private: int m_maxItems; /* HIIIIIIIIIIIIIER */ public: DragDropStringListModel ( QObject * parent = 0 ) : QStringListModel(parent), m_maxItems(-1) {} /* HIIIIIIIIIIIIIER */ DragDropStringListModel ( const QStringList & strings, QObject * parent = 0 ) : QStringListModel(strings, parent), m_maxItems(-1) {} /* HIIIIIIIIIIIIIER */ void setMaxItems(int nr = -1) { if (nr > 0 && nr < stringList().size()) m_maxItems = nr; else m_maxItems=-1; } /* HIIIIIIIIIIIIIER */ bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { if (action == Qt::IgnoreAction) return true; if (!data->hasFormat("application/vnd.text.list")) return false; if (column > 0) return false; if (m_maxItems == stringList().size()) /* HIIIIIIIIIIIIIER */ return false; // usw. } };
sollte tun ...
-
Naja, etwas. Also erstmal hab ich ne Methode zum setzen der m_maxPlatz geschrieben. Dann prüf ich in der
Qt::DropActions supportedDropActions() const
Ob Maxplatz -1 ist, oder ne Hilfsvariable z < Maxplatz. Wenn das gegeben ist, dann ActionMove, wenn nicht ActionIgnore.
Nur wenn ActionMove ist, wird ja dann diebool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
durchlaufen, dort erhöhe ich die hilfsvariable z um 1.
Und genau da ist das Problem ... denn sowohl von Rechts nach Links, als auch von Links nach rechts, wird ja z um 1 größer. Helfen würde mir nun, wenn ich die Richtung unterscheiden könnte, und danach z erhöhe oder verringere. Aber hier komm ich nicht weiter ....
Nen wirklich anderen Lösungsansatz hab ich irgendwie nicht gefunden, weil ich ja kein Objekt auf meine Vas-Klasse erstellen will, womit ich die größe der Stringliste in m1 bzw m2. auslesen könnte. Denn ich würde gern die hierfür erstelle model.h gern an deren Stelle im Programm wieder verwenden.
-
Hilfsvariable z HÄH? ... schau dir meinen CodePost wo
/* HIIIIIIIIIIIIIER */
steht ...Bei der Instanziierung
DragDropStringListModel m1; DragDropStringListModel m2; QTreeView v1; QTreeView v2; v1.setModel(m1); v2.setModel(m2); m2.setMaxItems(10);
Feddich ist ... dann prüft das eine model beim dropppen nicht ( da maxAnzahl auf -1) das andere prüft (da maxAnahl>-1). Das DragDropStringListModel erbt von QStringListModel und wird doch wohl noch seine eigene stringList().size() abfragen dürfen!?! Ich hoffe du trennst das auch wieder in .cpp und .h auf ... ich poste das hier nur so reinimplementiert weil das fürs Forum kürzer ist ... in die .h nur die Bekanntmachung der Methoden, in die .cpp die Implementierung !!
-
nalamar schrieb:
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
Wenn ich das richtig deute sagt dir
action
was passieren soll ... ist das nicht möglich returnierst du false, sonst machst du es und returnierst true ... du kannst natürlich die action beliebig umsetzen, das hat aber keine Konsequenz da die als Kopie hier reinkommt und all deine Änderungen am Ende der Methode null und void sind ...
-
Sorry, ich hab dein Edit-Code-Beispiel erst jetzt gesehen, da hatte ich schon geantwortet. Ja, zu 90% sah mein Code auch so aus.
Nur das hatte ich nicht.if (m_maxItems == size()) /* HIIIIIIIIIIIIIER */ return false;
Dort hatte ich eben ein z++; und hab eben in den supportedDropActions geschaut ob z > m_maxPlatz wird.
Und das size() meint der Kompiler ist nicht deklariert in dem Scope. Mal ganz abgesehen davon das ich so ziemlich jede Variante durchversucht haben mit parent und QModelIndex an irgend ne verwertbare Größe zu kommen und was weiß ich nicht alles, ich komme eben nun mal nicht an die Size der Stringliste .... aber ich tu mein bestes das noch rauszufinden .....
EDIT sagt: Ok ich sehe du hast dein Posting nochmal abgeändert, dann vergiss erstmal was ich geschrieben habe ... ich setze erstmal um was ich nun daraus an erkenntniss gewonnenhabe, sieht grad gut aus
-
Sooo .... nach 3 Bissen in die Tischkante funktioniert nun alles ....
Erstmal hatte ich das Problem das m_maxPlatz irgendwie nicht größer als -1 wurde .... bis mir dann auffiel das ich aus deinem Codebeispiel von Seite 1 noch folgendes hatte
m1 = new DragDropStringListModel(QString("1,2,3,4,5,6").split(","), this); m2 = new DragDropStringListModel(QStringList(), this);
Nach 5 mal durchlesen und verzweifeln das abgeändert .... und fast am Ziel gewesen. Dann blieb folgendess Problem - wenn ich die Überprüfung auf size>m_maxPlatz wirklich in die
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
Funktion packe, und die size+1>maxPlatz wird, ist es egal ob du false oder true returnierst, das DragItem verschwindet im Nichts. Also Back zu meiner Ursprünglichen Idee und das ganze nun so aufgebaut.
Qt::DropActions supportedDropActions() const { if (m_maxPlatz == -1 || stringList().size()+1 <= m_maxPlatz) { return Qt::MoveAction; } else { return Qt::IgnoreAction; } }
Und es funktioniert genau so wie ich mir das gewünscht habe. Padreigh, ich danke für deine Engelsgeduld.
Ich wünsche dir eine Gute Nacht !
EDIT: Mist, ich korrigiere meine Aussage. Wenn MaxPlatz erreicht wird funktioniert auch das zurückdraggen nicht mehr *grübel*
EDIT2: Ok, sobald das Draggen beginnt wird das erstmal mal supportedActions aufgerufen, da das Item dabei aber noch auf dem Focus der Liste ist, die Beschränkt ist, kommt als supportedaction "IgnoreAction" und das zurückdraggen funktioniert nicht. Also muss ich eine 3. Stelle finden, wo die Abfrage auf Beschränkung sinn macht.
-
Die Api hilft dir weiter ...
Qt::DropActions QAbstractItemModel::supportedDragActions () const
: Returns the actions supported by the data in this model. The default implementation returns supportedDropActions() unless specific values have been set with setSupportedDragActions().Qt::DropActions QAbstractItemModel::supportedDropActions () const [virtual]: Returns the drop actions supported by this model. The default implementation returns Qt::CopyAction. Reimplement this function if you wish to support additional actions. You must also reimplement the dropMimeData() function to handle the additional operations.
Knobeln ist beim Proggen der halbe Spass, sorry das ich ihn dir klaue
-
Läuft nun rund wie ein Buslenker .... danke sehr .....
Meine erste Idee war ja die dropMimedata umzuschreiben, das wenn size>m_maxplatz das gedragtte item einfach wieder bei der source hinten angefügt wird ... das es natürlich sooo einfach geht ..... sehr gut, nun kann ich das Kapitel endlich komplett abschließen
*verneig*
Der Nala
-
Zumindest kenn ich mich nu mit DnD auch ein wenig besser aus ... pack doch noch ein [solved] an den Thread dran ...
-
Machter sofort.
Eine letzte kleine Frage noch.
m2.setSupportedDragActions(Qt::MoveAction);
Und es läuft wie geschmiert, da ich ja nun aber weiß das ich vergesslich bin, dachte ich mir füge ich in die model.h folgendes ein:
Qt::DropActions supportedDragActions() const { return Qt::MoveAction; }
Das bringt nicht den gewünschten Erfolg - was hab ich schon wieder übersehen ?
-
"virtual" ist hier das Zauberwort
Und die Doku! Da steht auch genau drinnen, was sich wann wie verhält. padreigh hat das vorher auch schon (fast) komplett zitiert.
-
Gut,
http://www.exforsys.com/tutorials/c-plus-plus/c-virtual-functions.html war dazu sehr aussagekräftig ... also nicht vergesslich sein