Seite 1 von 1

QList die aus mehreren Klassenelementen besteht sortieren

Verfasst: 6. Februar 2007 13:35
von Locutus
Ich arbeite in meinem Programm mit einer QList, in der ich die Daten einer Klasse reinpacke.

Diese Klasse besteht u.a. aus Dateiname und Dateigröße. Ich würde nun gerne diese QList nach der Dateigröße sortieren. Allerdings geht das scheinbar nicht und die Anleitung geht da nicht drauf ein.
Ist es trotzdem möglich?

Ich habe das Problem bei mir so gelöst, daß ich eine zweite QList benutze, wo ich die Dateigrößen reinpacke und dort sortiere. Allerdings wäre es praktisch, wenn das auch mit nur einem Container gehen würde.

Gruß,
Locutus

Verfasst: 6. Februar 2007 14:05
von Christian81
Was ist gegen qSort() einzuwenden?

Verfasst: 6. Februar 2007 14:24
von Locutus
Christian81 hat geschrieben:Was ist gegen qSort() einzuwenden?
Mit qSort habe ich es anfangs auch direkt versucht, aber da bekomme ich nur Compiler-Fehler.
Der Aufruf sieht wie folgt aus:

Code: Alles auswählen

qSort(Alle_Dateien.begin(), Alle_Dateien.end());
Man müßte irgendwie noch angeben, daß man nach unsigned long int Dateigroesse sucht, aber alles was ich bisher versucht habe hat leider nicht geklappt.

Code: Alles auswählen

g:\temp\qt\include\qtcore\../../src/corelib/tools/qalgorithms.h(156) : error C2678: Binärer Operator '<': Es konnte kein Operator gefunden werden, der einen linksseitigen Operanden vom Typ 'const Dateien_Container' akzeptiert (oder keine geeignete Konvertierung möglich)
        g:\temp\qt\include\qtcore\../../src/corelib/tools/qchar.h(289): kann 'bool operator <(QChar,QChar)' sein
        g:\temp\qt\include\qtcore\../../src/corelib/tools/qbytearray.h(445): oder "bool operator <(const QByteArray &,const QByteArray &)"
        g:\temp\qt\include\qtcore\../../src/corelib/tools/qbytearray.h(447): oder "bool operator <(const QByteArray &,const char *)"
        g:\temp\qt\include\qtcore\../../src/corelib/tools/qbytearray.h(449): oder "bool operator <(const char *,const QByteArray &)"
        g:\temp\qt\include\qtcore\../../src/corelib/tools/qstring.h(788): oder "bool operator <(const char *,const QString &)"
        bei Anpassung der Argumentliste '(const Dateien_Container, const Dateien_Container)'
        g:\temp\qt\include\qtcore\../../src/corelib/tools/qalgorithms.h(155): Bei der Kompilierung der  Klassen-template der bool qLess<T>::operator ()(const T &,const T &) const-Memberfunktion
        with
        [
            T=Dateien_Container
        ]
        g:\temp\qt\include\qtcore\../../src/corelib/tools/qalgorithms.h(401): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "qLess<T>".
        with
        [
            T=Dateien_Container
        ]
        g:\temp\qt\include\qtcore\../../src/corelib/tools/qalgorithms.h(175): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "void QAlgorithmsPrivate::qSortHelper<RandomAccessIterator,T>(RandomAccessIterator,RandomAccessIterator,const T &)".
        with
        [
            RandomAccessIterator=QList<Dateien_Container>::iterator,
            T=Dateien_Container
        ]
        .\algo.cpp(222): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "void qSort<QList<T>::iterator>(RandomAccessIterator,RandomAccessIterator)".
        with
        [
            T=Dateien_Container,
            RandomAccessIterator=QList<Dateien_Container>::iterator
        ]
Am besten ich poste mal ein wenig Code. Also die Klasse sieht wie folgt aus:

Code: Alles auswählen

class Dateien_Container{
public:
	QString Dateiname;
	QString Dateiname_ohne_Pfad;
	unsigned long int Dateigroesse;
};
Den Container erzeuge ich so:

Code: Alles auswählen

QList<Dateien_Container> Alle_Dateien;
Aber wie man jetzt nach Dateigröße sortiert, habe ich noch nicht hinbekommen. Bei all meinen bisherigen Versuchen hagelte es Fehlermeldungen.
Deswegen bin ich auch den Umweg über einen zweiten Container gegangen, würde aber gerne wissen ob das auch mit nur einen Container gehen würde.

Verfasst: 6. Februar 2007 14:28
von Christian81
Ich würde mal sagen: RTM!
This function requires the item type (in the example above, int) to implement operator<().
Ach ja - die Dateigrösse würde ich dann auch gleich mit Qt-Mitteln beschreiben -> qint64

Verfasst: 6. Februar 2007 14:45
von Locutus
Christian81 hat geschrieben:Ich würde mal sagen: RTM!
RTM?
This function requires the item type (in the example above, int) to implement operator<().
Ja genau das ist der Punkt, worüber ich bisher gestolpert bin und weswegen ich der Meinung war, es geht eventuell nicht.
Ich weiß nicht was ich für int einsetzen soll.
Sortieren kann man ja z.B. hiermit: qSort(Alle_Dateien.begin(), Alle_Dateien.end(), qGreater<int>()); - so mache ich es bei meinem zweiten Container.
Normalerweise müßte ich ja nur dem Compiler sagen, daß er von der Klasse "unsigned long int Dateigroesse;" benutzen soll, aber über Alle_Dateien habe ich keinen direkten Zugang darauf.

Ist vermutlich 'ne einfache Sache, habe aber in der Literatur leider keine konkrete Hilfe gefunden.
Ach ja - die Dateigrösse würde ich dann auch gleich mit Qt-Mitteln beschreiben -> qint64
Okay danke, werde ich machen.

Verfasst: 6. Februar 2007 14:51
von franzf
schreib dir doch eine Funktion sort( SortValue ).
SortValue ist ein enum (welchen du selber definieren musst), mit dem du wählen kannst, nach welchem Element sortiert werden soll. Als Methode deiner Klasse definiert sortiert sie direkt den als Member deklarierten QList mit deinen Dateien.
Kannst natürlich genauso vorgehen wie bei qSort mit begin() und end() + SortValue.

Grüße
Franz

Verfasst: 6. Februar 2007 15:01
von Christian81
Locutus hat geschrieben:[
This function requires the item type (in the example above, int) to implement operator<().
Ja genau das ist der Punkt, worüber ich bisher gestolpert bin und weswegen ich der Meinung war, es geht eventuell nicht.
Ich weiß nicht was ich für int einsetzen soll.
Ich würde sagen C++ in 21 Tagen, Tag 20 (jetzt hoffe ich nur dass ich die Syntax richtig hinbekomme ;) )

Code: Alles auswählen

 bool operator<(const QList<Dateien_Container> &t1, const QList<Dateien_Container> &t2)
 {
        return (t2.Dateigroesse < t1.Dateigroesse);
 }

Verfasst: 6. Februar 2007 15:08
von franzf
Christian81 hat geschrieben:

Code: Alles auswählen

 bool operator<(const QList<Dateien_Container> &t1, const QList<Dateien_Container> &t2) const
 {
        return (t2.Dateigroesse < t1.Dateigroesse);
 }
Oh, hab ich da was falsch verstanden? Ich dachte er hat ne Klasse (o.ä.) in der er Attribute (Name, Größe, etc) einer Datei speichert. Diese sammelt er in einer QList. Nun möchte er diese Liste sortieren nach einem bestimmten Kriterium (z.B. Größe). Eben so wie es in einem Dateimanager bei der "Detaillierte Liste" (oder so) möglich ist, wo man diese Dateien auch nach verschiedenen Kriterien sortieren kann.
(anders könnte ich mir das auch gar nicht vorstellen...)

Grüße
Franz

// Nachtrag:
QList hat doch kein Attribut namens Dateigroesse, oder? :D

Verfasst: 6. Februar 2007 16:23
von Locutus
Also dann sag ich erst einmal danke für die ganzen Antworten. Das Buch C++ in 21 Tagen habe ich nicht, werde ich mir aber besorgen, hört sich interessant an.
Vor allem wenn die Thematik darin genauer besprochen wird.

@franzf
Dein Vorschlag mit enum hört sich auch sehr gut an, werde mir das alles in Ruhe mal angucken, habe bisher mit enum noch nichts gemacht.
// Nachtrag:
QList hat doch kein Attribut namens Dateigroesse, oder? :D

Ja, das gehört zu meiner Klasse, genau wie du es in deinem Post gesagt hast :)
Bin froh das man das Problem auch ohne zweiten Container lösen kann und werde mich die Tage dransetzen, wenn ich mehr Zeit habe.

Also nochmals besten Dank euch allen.

Verfasst: 6. Februar 2007 17:14
von Christian81
Locutus hat geschrieben:Also dann sag ich erst einmal danke für die ganzen Antworten. Das Buch C++ in 21 Tagen habe ich nicht, werde ich mir aber besorgen, hört sich interessant an.
Vor allem wenn die Thematik darin genauer besprochen wird.
Stop, das war ein Scherz :)
Wenn, könnte es ungefähr bei Tag 20 rum auftauchen - Templates & Operatoren.

Sorry :)

Verfasst: 21. Februar 2007 10:50
von stevy

Code: Alles auswählen

class Dateien_Container {
public:
   QString Dateiname;
   QString Dateiname_ohne_Pfad;
   unsigned long int Dateigroesse;

   // neuer Operator
   bool operator<(const Dateien_Container& dc) {
      return Dateigroesse < dc.Dateigroesse;
   }
};

Verfasst: 21. Februar 2007 19:47
von Locutus
Danke für deine Rückmeldung, stevy :)
Bei mir sieht der Codeabschnitt so aus:

Code: Alles auswählen

inline bool operator<( const Dateien_Container& lhs, const Dateien_Container& rhs){
  return (lhs.Dateigroesse < rhs.Dateigroesse);
}
Sortiert kann dann ganz normal über qSort werden, für alle zur Info, die vielleicht irgendwann mal vor demselben Problem stehen.