PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : qlistview -> nach Wochentagen sortieren



doitux
04-03-2006, 23:01
Hallo

Ich möchte eine qlistview-Liste machen in dem Termine im Format "Wochentag - Uhrzeit" aufgelistet sind. Mit diesem Format werden immerhin die Uhrzeiten an einem Wochentag aufsteigend sortiert. Nun werden die Wochentage leider auch aufsteigend alphabetisch sortiert.
Wie kann ich es erreichen dass die Wochentage logisch aufsteigend sortiert werden. Also Montag, Dienstag, Mittwoch, ... anstatt Dienstag, Donnerstag, Mittwoch, ....
Ich hatte die Idee am Anfang des Strings bei Montag eine 1 bei Dienstag eine 2 usw zu schreiben. Allerdings hab ich noch keine Möglichkeit gefunden dieses erste Zeichen in dem String zu verstecken bzw. in weißer Schrift darzustellen.

Vielleicht geht das alles noch viel einfacher. Hat jemand einen Tip für mich?

Gruß
doitux

Caveman
05-03-2006, 10:22
Weise doch denn Wochentagen die Zahlen 1 bis 7 zu und wenn Du sie anzeigen willst, lässt Du für die 1 Montag, für die 2 Dienstag usw. ausgeben.

Die Wochentagen selbst kannst Du nicht so einfach sortieren, Du musst es dem Computer schon irgendwie ermöglichen, dass er mit dieser Aufgabe zurecht kommt.

doitux
07-03-2006, 03:41
Ich glaub dann muss ich mit QListViewItem::compare ran oder? Klingt jedenfalls danach.

anda_skoa
07-03-2006, 14:10
Ja, korrekt.

Ist relativ leicht compare() für die Spalten zu überschreiben, wo man lieber interne Daten vergleichen will statt den Strings der Darstellung.

Ciao,
_

doitux
09-03-2006, 09:09
Hallo

Erstmal danke für die Tips. Wenn ich jetzt allen Items mit dem Wochentag Montag einen Key=1 gebe dann werden aber nicht die Uhrzeiten dahinter sortiert. Auf dem Bildschirmfoto im Anhang kann man sehen wie das momentan aussieht. Am wichtigsten ist mir, dass die Uhrzeiten pro Tag sortiert sind, da die Schüler in dieser Reihenfolge zum Unterricht kommen und ich nicht in der Liste hin und her klicken will.

Ich hab das schon mal mit zwei separaten Feldern für Uhrzeit und Wochentag probiert aber damit konnte ich dann nur entweder nach Uhrzeit oder nach Wochentag sortieren.

Hat jemand eine Idee wie man die Sortierung von Tag und Uhrzeit unter einen Hut bekommt?

Caveman
09-03-2006, 15:27
Wie wäre es denn, wenn Du beides zusammenführst und dann erst sortierst?

1:09:30 steht dann für Montag um 9:30h.
Oder auch 10930.

anda_skoa
09-03-2006, 18:21
Am besten das Datum mit Zeit als QDateTime in der Item Instanz als Membervariable halten und dann bei compare das DateTime des aktuellen Items mit dem DateTime des anderen vergleichen, siehe QDateTime::secsTo

zB



MyListViewItem* other = static_cast<MyListViewItem(*item);
return date.secsTo(other->date);


Ciao,
_

doitux
10-03-2006, 08:41
@Caveman:

Jo das klingt gut. kann ich den den key-wert eines items setzen? setKey gibts ja für qlistviewitem nicht. Ich hab schon überlegt "1:09:30" in eine versteckte spalte einzutragen. Oder geht das noch sauberer?

@anda_skoa:

Danke für den Hinweise. Leider kann ich mir mit meinen bisherigen Kenntnissen nicht vorstellen wie ich das anwenden soll. Ich versuche das gerade mit dem Beispiel aus der Trolltec-Doku zusammenzubringen:


int MyListViewItem::compare( QListViewItem *i, int col,
bool ascending ) const
{
return key( col, ascending ).compare( i->key( col, ascending) );
}

So richtige hab ich das auch noch nicht verstanden wie das mit dem compare gehen soll. Vielleicht kannst du mir da auf die Sprünge helfen. Man soll also MyListViewItem von QListViewItem ableiten? Oder kann man das auch einfach in einer Elementfunktion des Hauptprogramms machen? Compare übergibt man ein QListViewItem. Und compare() vergleicht dieses dann womit? Und was passiert mit dem integer-Wert der dabei rauskommt?
Sorry aber da hakt es im Augenblick bei mir.

anda_skoa
10-03-2006, 21:01
Das ist ansich relativ einfach

Sagen wir du hast ein Item und in Spalte 0 ein Datum


class MyItem : public QListViewItem
{
public:
MyItem(QListView* view, const QDateTime& date, const QString& text);

virtual int compare(QListViewItem* item, int col, bool ascending) const;

private:
QDateTime m_date;
};

MyItem::MyItem(QListView* view, const QDateTime& date, const QString& text)
: QListViewItem(view),
m_date(date)
{
setText(0, m_date.toString("yyyy-MM-dd"); // zB nur Datum
setText(1, text);
}

int MyItem::compare(QListViewItem* item, int col, bool ascending) const
{
// nur erste spalte selber vergleichen
if (col != 0) return QListViewItem:compare(item, col, ascending);

MyItem* other = static_cast<MyItem*>(item);
return other->m_date.secsTo(m_date);
}


Ciao,
_

doitux
11-03-2006, 01:51
Hallo anda_skoa

Ich hab jetzt mal versucht beide Ansätze versucht zusammen zu bringen. Das QDateTime hab ich verworfen weil ich ja als QDateTime-Input keine Feld habe in dem ich z.B. Montag, Dienstag, usw habe. Das hab ich über eine QCombobox realisiert. Diese spuckt die Wochentagsnamen als String aus die später in IDs umgewandelt werden. Also Montag = 1 Dienstag = 2 usw.
Nun mal zu meinem ersten kläglichen Versuch:


#ifndef MYITEM_H
#define MYITEM_H

#include <qlistview.h>

class MyItem : public QListViewItem
{
public:
MyItem(QListView* view, const QString& name, const QString& sorter, const QString& time);
//name = Schülername (z.B. Lieschen Müller) sorter = 021445 (für Dienstag 14:45 Uhr) time = "Dienstag 14:45" als QString

virtual int compare(QListViewItem* item, int col, bool ascending) const;
virtual int getsorterint(const QString& sorter) const;

private:
QString compsorter;
};

MyItem::MyItem(QListView* view, const QString& name, const QString& sorter, const QString& time)
: QListViewItem(view),
compsorter(sorter)
{

setText(0, name);
setText(1, time);
compsorter=sorter;

}

int MyItem::compare(QListViewItem* item, int col, bool ascending) const
{
// nur erste spalte selber vergleichen
if (col != 1) return QListViewItem::compare(item, col, ascending);

MyItem* other = static_cast<MyItem*>(item);
return other->getsorterint(compsorter)-getsorterint(compsorter);
//hier wollte ich einfach die Differenz von dem einen sorter und dem von other zurückgeben lassen in der Hoffung dass das dann klappt.
}

int MyItem::getsorterint(const QString& sorter) const
{
int sorterint;
bool ok;
sorterint = sorter.toInt(&ok, 10);
return sorterint;
}

#endif

Leider kann ich das nicht testen da ich folgende Fehlermeldung beim kompileren bekomme:



cd '/home/doitux/Projekte/qt-c++/qupil/' && QTDIR="/usr/qt/3" gmake -j1
test -d bin/ || mkdir -p bin/
Linken der Datei bin/qupil (g++)
obj/qupiladdpupilimpl.o: In function `MyItem::compare(QListViewItem*, int, bool) const':
qupiladdpupilimpl.cpp:(.text+0x16c): multiple definition of `MyItem::compare(QListViewItem*, int, bool) const'
obj/qupil.o:qupil.cpp:(.text+0x16c): first defined here
obj/qupiladdpupilimpl.o: In function `MyItem::getsorterint(QString const&) const':
qupiladdpupilimpl.cpp:(.text+0x1d8): multiple definition of `MyItem::getsorterint(QString const&) const'
obj/qupil.o:qupil.cpp:(.text+0x1d8): first defined here
obj/qupiladdpupilimpl.o: In function `MyItem::MyItem(QListView*, QString const&, QString const&, QString const&)':
qupiladdpupilimpl.cpp:(.text+0x0): multiple definition of `MyItem::MyItem(QListView*, QString const&, QString const&, QString const&)'
obj/qupil.o:qupil.cpp:(.text+0x0): first defined here
obj/qupiladdpupilimpl.o: In function `MyItem::MyItem(QListView*, QString const&, QString const&, QString const&)':
qupiladdpupilimpl.cpp:(.text+0xb6): multiple definition of `MyItem::MyItem(QListView*, QString const&, QString const&, QString const&)'
obj/qupil.o:qupil.cpp:(.text+0xb6): first defined here
obj/qupilmainwindowimpl.o: In function `MyItem::compare(QListViewItem*, int, bool) const':
qupilmainwindowimpl.cpp:(.text+0x16c): multiple definition of `MyItem::compare(QListViewItem*, int, bool) const'
obj/qupil.o:qupil.cpp:(.text+0x16c): first defined here
obj/qupilmainwindowimpl.o: In function `MyItem::getsorterint(QString const&) const':
qupilmainwindowimpl.cpp:(.text+0x1d8): multiple definition of `MyItem::getsorterint(QString const&) const'
obj/qupil.o:qupil.cpp:(.text+0x1d8): first defined here
obj/qupilmainwindowimpl.o: In function `MyItem::MyItem(QListView*, QString const&, QString const&, QString const&)':
qupilmainwindowimpl.cpp:(.text+0x0): multiple definition of `MyItem::MyItem(QListView*, QString const&, QString const&, QString const&)'
obj/qupil.o:qupil.cpp:(.text+0x0): first defined here
obj/qupilmainwindowimpl.o: In function `MyItem::MyItem(QListView*, QString const&, QString const&, QString const&)':
qupilmainwindowimpl.cpp:(.text+0xb6): multiple definition of `MyItem::MyItem(QListView*, QString const&, QString const&, QString const&)'
obj/qupil.o:qupil.cpp:(.text+0xb6): first defined here
obj/qupilbirthdayreminderimpl.o: In function `MyItem::compare(QListViewItem*, int, bool) const':
qupilbirthdayreminderimpl.cpp:(.text+0x16c): multiple definition of `MyItem::compare(QListViewItem*, int, bool) const'
obj/qupil.o:qupil.cpp:(.text+0x16c): first defined here
obj/qupilbirthdayreminderimpl.o: In function `MyItem::getsorterint(QString const&) const':
qupilbirthdayreminderimpl.cpp:(.text+0x1d8): multiple definition of `MyItem::getsorterint(QString const&) const'
obj/qupil.o:qupil.cpp:(.text+0x1d8): first defined here
obj/qupilbirthdayreminderimpl.o: In function `MyItem::MyItem(QListView*, QString const&, QString const&, QString const&)':
qupilbirthdayreminderimpl.cpp:(.text+0x0): multiple definition of `MyItem::MyItem(QListView*, QString const&, QString const&, QString const&)'
obj/qupil.o:qupil.cpp:(.text+0x0): first defined here
obj/qupilbirthdayreminderimpl.o: In function `MyItem::MyItem(QListView*, QString const&, QString const&, QString const&)':
qupilbirthdayreminderimpl.cpp:(.text+0xb6): multiple definition of `MyItem::MyItem(QListView*, QString const&, QString const&, QString const&)'
obj/qupil.o:qupil.cpp:(.text+0xb6): first defined here
obj/moc_qupilmainwindowimpl.o: In function `MyItem::compare(QListViewItem*, int, bool) const':
moc_qupilmainwindowimpl.cpp:(.text+0x16c): multiple definition of `MyItem::compare(QListViewItem*, int, bool) const'
obj/qupil.o:qupil.cpp:(.text+0x16c): first defined here
obj/moc_qupilmainwindowimpl.o: In function `MyItem::getsorterint(QString const&) const':
moc_qupilmainwindowimpl.cpp:(.text+0x1d8): multiple definition of `MyItem::getsorterint(QString const&) const'
obj/qupil.o:qupil.cpp:(.text+0x1d8): first defined here
obj/moc_qupilmainwindowimpl.o: In function `MyItem::MyItem(QListView*, QString const&, QString const&, QString const&)':
moc_qupilmainwindowimpl.cpp:(.text+0x0): multiple definition of `MyItem::MyItem(QListView*, QString const&, QString const&, QString const&)'
obj/qupil.o:qupil.cpp:(.text+0x0): first defined here
obj/moc_qupilmainwindowimpl.o: In function `MyItem::MyItem(QListView*, QString const&, QString const&, QString const&)':
moc_qupilmainwindowimpl.cpp:(.text+0xb6): multiple definition of `MyItem::MyItem(QListView*, QString const&, QString const&, QString const&)'
obj/qupil.o:qupil.cpp:(.text+0xb6): first defined here
collect2: ld gab 1 als Ende-Status zurück
gmake: *** [bin/qupil] Fehler 1
*** Beendet mit Status: 2 ***



Ich kann das leider überhaut nicht deuten. Kennst du solche Meldungen? Warscheinlich hab ich da irgendwas vermurkst :confused:

anda_skoa
11-03-2006, 16:56
Die Funktionen scheinen in mehr als einem CPP File zu sein.

Nachdem du einen String als Kriterum hast, kannst du einfacher key() überschreiben und bei col == 1 den Datumsstring zurückgeben.

compare brauchst du dann nicht extra zu implementieren.

also in etwa


QString MyItem::key(int col, bool ascending) const
{
if (col == 1) return compsorter;
return QListViewItem::key(col, ascending);
}


Ciao,
_

doitux
13-03-2006, 11:53
vielen Dank. Jetzt klappt es so wie es soll.

Gruß
doitux

doitux
15-03-2006, 01:13
Hi ich hab jetzt noch ein kleines Problem wenn ich einen key mit dem "Sorter" im nachhinein setzen will. Ich hab mir dafür die Funktion setKey in die Klasse MyItem mit reingenommen:


void MyItem::setKey(int col, const QString& setkeysorter)
{
if (col == 1) compsorter=setkeysorter;
}

Wenn ich das dann anwenden will (also den Sorter eines geänderten MyItems ändern) mache ich:


MyItem* selecteditem = listView1->selectedItem();
[...]
selecteditem->setKey(1, "1"+timeEdit1_2->time().toString("hh:mm").remove(":"));


Beim Kompilieren gibts dann allerdings diese Meldung:

Fehler: Ungültige Umformung von »QListViewItem*« in »MyItem*«

Allerdings hab ich ja ganz am Anfang als ich die Liste erstellt hab das ganze so angestellt:


MyItem* item;
item = new MyItem(listView1, completeName, sorter, temp);

Also sind doch die Items in der listView1 MyItems oder nicht? Warum dann diese Fehlermeldung?

Gruß
doitux

anda_skoa
15-03-2006, 20:56
Du brauchst einen Cast, weil der Compiler von QListView::selectedItem nur weiß, daß es ein QListViewItem zurückliefert, nicht daß du MyItems benutzt



MyItem* item = static_cast<MyItem*>(listView->selectedItem());


Ciao,
_

doitux
16-03-2006, 00:35
nochmal Danke. Hat wieder voll gepasst. Jetzt geh ich erstmal n bischen was über static_cast lesen.