Listenreihenfolge manipulieren

Alles rund um die Programmierung mit Qt
heinzbr
Beiträge: 16
Registriert: 24. Dezember 2008 14:41

Listenreihenfolge manipulieren

Beitrag von heinzbr »

Hallo,
ich bin neu bei QT ;-) und suche eine Möglichkeit oder ein Widget,
bei dem man die Reihenfolge der Einträge manipulieren kann.

Ich habe mir schon DragAndDrop angesehen, aber das hat zu viele
"Freiheitsgrade". Eigentlich würde mir das Hoch/Runterschieben in
einer Liste mit der Maus genügen.

Gibt's da schon was ?
Bzw. wie macht man das am besten ?

Gruss & Danke
Heinz
gboelter
Beiträge: 80
Registriert: 5. Dezember 2007 14:52
Wohnort: Davao City, Philippines

Re: Listenreihenfolge manipulieren

Beitrag von gboelter »

heinzbr hat geschrieben:Eigentlich würde mir das Hoch/Runterschieben in
einer Liste mit der Maus genügen.
Auch auf die Gefahr hin, dass ich Dein problem falsch verstanden habe:

Aber wenn Du was ganz Einfaches haben willst, dan koenntest Du das betreffende Element markieren und dann auf einen Button fuer "hoch" oder "runter" klicken. Entsprechend loescht Du dann das Element aus der Liste und fuegst es an neuer Position wieder ein.
Guenther
Davao City, Philippines, Planet Earth, 28°C

Qt 4.8.1 for Linux/X11 - Open Source Edition for Application Development
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Schau dich mal im assistant um, das schadet nie ;)
Zu deinem Problem:
Die Basisklasse aller "View"s (Table, List, etc...) ist "QAbstractItemView".
Da gibt es das Property "dragDropMode".
Wenn du dieses auf "InternalMove" setzt, kannst du Items im View rumschieben.
Für alphabetisches sortieren such im assistant mal nach "sortingEnabled".

Grüße
Franz
gboelter
Beiträge: 80
Registriert: 5. Dezember 2007 14:52
Wohnort: Davao City, Philippines

Beitrag von gboelter »

franzf hat geschrieben:Da gibt es das Property "dragDropMode".
Wenn du dieses auf "InternalMove" setzt, kannst du Items im View rumschieben.
Die Funktion scheint aber nicht ganz sauber zu arbeiten.

Ich habe "dragDropMode = InternalMove" vor einigen Tagen mal in einem TreeWidget anwenden wollen. Ich kann dann auch Eintraege mit der Maus verschieben, aber leider nur 2 x. Ab dem dritten Mal verschwinden dann die verschobenen Eintraege in meinem Widget, es werden also immer weniger Eintraege angezeigt. Ein Neustart des Widgets hilt nicht weiter, nur ein Neustart des Programms selbst.

EDIT: Ich vergass zu erwaehnen, dass besagtes Widget mittels Designer erstellt wurde, es also bis auf die main.cpp keinen eigenen code gibt, der Ursache fuer das Fehlverhalten sein koennte.

Hatte aber leider noch keine Zeit das mal naeher zu untersuchen.

QT-4.4.3/X11
Guenther
Davao City, Philippines, Planet Earth, 28°C

Qt 4.8.1 for Linux/X11 - Open Source Edition for Application Development
heinzbr
Beiträge: 16
Registriert: 24. Dezember 2008 14:41

Beitrag von heinzbr »

Sorry fuer die spaete Anwort... war offline die letzten Tage ;-)
InternalMove war das was ich gesucht hatte.
Ich werde das demnaechst mal probieren und berichten.
Danke.
Heinz
heinzbr
Beiträge: 16
Registriert: 24. Dezember 2008 14:41

Beitrag von heinzbr »

So, jetzt hab ich's mal probiert.
"InternalMove" funktioniert zwar, aber leider kann man auch auf einem
vorhandenen Listeneintrag "droppen" und diesen damit ueberschreiben.
Loescht man im ListModel an allen Items das Qt::ItemIsDropEnabled flag
kann man nirgends mehr "droppen".

Gibts dafuer auch noch eine Loesung, dass die Items einfach aufrutschen ?
Ich haette ja gern nur die Reihenfolge per DragDrop geaendert...

Sonst bleibt mir echt nur noch die unelegante "Button" Loesung :-(

Gruss und Danke
Heinz
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Sonst bleibt mir echt nur noch die unelegante "Button" Loesung
grad die find ich eigentlich eleganter.
Naja, vielleicht treff ich mit der maus einfach nur ned so gut ^^

Du kannst beim DND natuerlich die funktionalitaet ueberschreiben, so das ein überschreiben der items per useraction ned möglich ist
Wenn er also ein item auf das andere zieht, er das item vor das andere legt.
Aber das muss man halt expliziet implementieren ....

deine "widgets" sind also Listen ?
Du solltest aber nicht anhand der verschiebemöglichkeit die art der liste auswaehlen, sondern nach anderen benoetigten Features.
Hoch runter verschiebung sowie DND unterstuetzen alle, bzw man kanns ihnen beibringen.

Ciao ...
heinzbr
Beiträge: 16
Registriert: 24. Dezember 2008 14:41

Beitrag von heinzbr »

Ja. Ich habe eine QStringList und sollte die vom Benutzer sortieren lassen.
Erschwerend kommt hinzu, dass es sich um viele solcher Listen in einer QTableView handelt....

[quote]Hoch runter verschiebung sowie DND unterstuetzen alle, bzw man kanns ihnen beibringen.[/quote]

Hast Du dazu ein Beispiel. Bei mir klappt's nicht.
Natuerlich kann ich im Model Hoch/Runter-Schieben.
Ach DND geht in der View.
Aber so wie ich beide kombinieren moechte klappt's nicht :-(
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

warum nimmt man fuer ne einfache liste nen QTableView ???
Das ist grad das komplizierteste :-)

Besipiel hab ich grad ned, ausserdem iss es kaum wahrscheinlich das man was passendes hat ...
Ist das wirklich nur ne Liste mit 1 Spalte ???
Darf der User die eintrage aendern, oder nur verschieben ?
sind die "Texte" mit irgendwas verknüpft ?

Verwendest du ein QStringListModel oder was eigenes ???

noch was:
QAbstractItemView::
dragDropOverwriteMode : bool

This property holds the view's drag and drop behavior.
If its value is true, the selected data will overwrite the existing item data when dropped, while moving the data will clear the item. If its value is false, the selected data will be inserted as a new item when the data is dropped. When the data is moved, the item is removed as well.
The default value is false, as in the QListView and QTreeView subclasses. In the QTableView subclass, on the other hand, the property has been set to true.
Note: This is not intended to prevent overwriting of items. The model's implementation of flags() should do that by not returning Qt::ItemIsDropEnabled.
This property was introduced in Qt 4.2.
Access functions:
bool dragDropOverwriteMode () const
void setDragDropOverwriteMode ( bool overwrite )
See also dragDropMode.
Ciao ...
heinzbr
Beiträge: 16
Registriert: 24. Dezember 2008 14:41

Beitrag von heinzbr »

Erstmal vorweg: Vielen Dank, dass du mir hilfst, ich bin naemlich am verzweifeln ;-)

QTableView deshalb, weil es um eine List von mehreren Informationen geht.
Das darunter liegende Modell hat mehrere Spalten mit QStrings und eben einer Spalte mit QStringListen.
Alle Spalten kann man editieren.
Die QString Spalten funktionieren ganz normal.
Bei der einen Spalte soll man die Reihenfolge der QStringList Eintraege (komfortable) aendern koennen.
Die Sache mit dem "dragDropOverwriteMode" habe ich gelesen und probiert, hat aber nicht geholfen :-(

Noch eine Idee, wie man ein cooles QItemDelegate machen kann, dass die eine Spalte handelt ?

Gruss Heinz
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Aehm, jetzt hab ich erstmal die 1000 fragezeichen ^^

Ok, du hasst eigentlich gar keine simple stringliste, sondern:

Irgendwas mit ner Stringliste und dann Einzelstrings in kombination ... ???
Wie genau sehen da die beziehungen zu aus, kann ich mir jetzt grad ned wirklich vorstellen ...

was hat das ganze mit nem Itemdelegate zu tun ? Oder iss das nen eigenstaendiges Problem ??? Also Du willst nen bestimmten Text durch nen entsprechendes Item in ner Spalte darstellen ???

Ciao ...
heinzbr
Beiträge: 16
Registriert: 24. Dezember 2008 14:41

Beitrag von heinzbr »

Sorry, wenn ich zu undeutlich war.
Hier eine kleine Ascii Grafik der Tabelle:

[code]
Hdr1 Hdr2 Hdr3
strA1 strA2 strA3a,strA3b,strA3c
strB1 strB2 strB3d,strB3e
strC1 strC2 strC3f,strC3g,strC3h,strC3i
[/code]

In Spalte 1 und 2 werden Strings angezeigt/Editiert.
In der Spalte 3 werden "kleine" Stringlisten als Komma-Separierte Liste angezeigt und sollen irgendwie manipuliert werden,
sodass man z.B. aus "strA3a,strA3b,strA3c" "strA3c,strA3a,strA3b" oder aus "strB3d,strB3e" "strB3e,strB3d" machen kann...
D.h. in Spalte 3 soll nur die Reihenfolge geaendert werden.

Gruss Heinz

Ist das so etwas klarer ?
Ich habe gedacht man macht fuer Spalte 3 einen speziellen Delegate.
Aber wenn's anderst gehen koennte bin ich fuer jede Loesung offen :-)
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

ok,
Also hasst du nen tableview, der ca so aussieht:

Code: Alles auswählen

-----------------------------------------------
| Hdr1  | Hdr2  | Hdr3                        |
-----------------------------------------------
| strA1 | strA2 | strA3a,strA3b,strA3c        | 
-----------------------------------------------
| strB1 | strB2 | strB3d,strB3e               |
-----------------------------------------------
| strC1 | strC2 | strC3f,strC3g,strC3h,strC3i |
-----------------------------------------------
Die ersten beiden spalten sollen die texte editierbar sein, bei der 3. spalte soll man nur die reihenfolge der texte aendern koennen.

Hab ich das richtig verstanden ?

Wie stellst dir das verhalten beim editieren der 3. spalte eigentlich vor ?
nen deligate zeichnet sich ja direkt in die tabelle ....
da ne eigene liste reinzeichnen lassen beim editieren waer ja .. urks
ich wuerd eher den click abfangen und ueber nen eigenes dialogfeld die reihenfolge verwalten lassen.

Ciao ....
heinzbr
Beiträge: 16
Registriert: 24. Dezember 2008 14:41

Beitrag von heinzbr »

Ja. Genau so sollte es aussehen.
Ich dachte ich koennte ein QItemDelegate bauen, dass einen Popupdialog als Editor erzeugt.
Nachdem das DragDrop nicht so richtig laeuft, gibt's wahrscheinlich noch zwei "Up"/"Down" Buttons zum verschieben in der Liste.
Was ich noch nicht weiss, ist ob/wann/wer den Dialog zerstoert ?
Ich habe bei dem erzeugten Editor QWidget "setWindowFlags(Qt::Popup)" gesetzt, weiss aber nicht ob das eine Gute Idee ist ?
So geht der Dialog schon beim "daneben" klicken weg, obwohl das ja eigentlich beim "emit closeEditor(editor)" vom delegate passiert, oder ?
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Das deligate brauchst du ja nur, wenn Du das aussehen, also das widget in der tabelle austauschen willst.
Willst du sowieso beim editieren nur nen eigenen dialog aufmachen, brauchst das ned, sondern kannst direkt das click abfangen den eigenen dialog aufmachen ..... zum erzeugen vom dialog brauchst kein deligate.

Anders waere, wenn du das edit feld lassen woelltes (QLineEdit ist der Standart view glaub ich) und daneben beim editieren nen button zeichnen woelltest, bei dem erst der dialog Quasi als hilfe auftaucht.

du kannst also QAbstractItemView::clicked oder
void QAbstractItemView::doubleClicked ( const QModelIndex & index )
anfangen und drauf reagieren

Ciao ...
Antworten