[gelöst] Sort in QTableWidget
[gelöst] Sort in QTableWidget
Hallo Leute.
Ich habe das Problem, dass QTableWidget Items mit mit formatierten Europreisen + ¤ Zeichen als Inhalt nicht richtig sortiert wird. Jetzt meine Frage: Kann ich irgendwie einen zweiten Datensatz für das Item hinterlegen, damit es richtig sortiert wird? Ich konnte bisher nichts brachbares finden.
Gruß
Jens
Ich habe das Problem, dass QTableWidget Items mit mit formatierten Europreisen + ¤ Zeichen als Inhalt nicht richtig sortiert wird. Jetzt meine Frage: Kann ich irgendwie einen zweiten Datensatz für das Item hinterlegen, damit es richtig sortiert wird? Ich konnte bisher nichts brachbares finden.
Gruß
Jens
Zuletzt geändert von dazedly am 4. Oktober 2010 22:37, insgesamt 3-mal geändert.
Das mit data und einer anderen Role habe ich schon versucht, aber welche Role soll das denn sein?
Zeigt das richtige an, aber Sortiert falsch.
Zeigt das falsche an, aber sortiert richtig.
Code: Alles auswählen
QTableWidgetItem *priceTableWidgetItem = new QTableWidgetItem(QString::number(therapy->getPrice(), 'f', 2).append(QString::fromUtf8("¤")));
priceTableWidgetItem->setData(Qt::UserRole, therapy->getPrice());
Code: Alles auswählen
QTableWidgetItem *priceTableWidgetItem = new QTableWidgetItem(QString::number(therapy->getPrice(), 'f', 2).append(QString::fromUtf8("¤")));
priceTableWidgetItem->setData(Qt::DisplayRole, therapy->getPrice());
Ist mir klar, dass du das schon erwähnt hattest. Nur steige ich da noch nicht ganz durch. Ich blicke mit der Qt Doku in diesem Punkt nicht durch und alles was ich sonst noch finde sind entweder Python beispiele, oder zu spezifische.
Ich stehe noch in den Anfängen mit Qt und habe dafür auch schon recht viel damit gemacht, aber ich blicke hier jetzt nicht ganz durch
Ich stehe noch in den Anfängen mit Qt und habe dafür auch schon recht viel damit gemacht, aber ich blicke hier jetzt nicht ganz durch
Ich habe mir jetzt mal die ganze Sache in diesem Tutorial (http://doc.trolltech.com/4.7/itemviews- ... egate.html) etwas genauer angesehen. Da wird Delegate benutzt um so ein Sternrating in einem QTableWidgetItem zu realisieren. Nur kann man selbst in diesem Tutorial nicht danach sortieren. Ich möchte doch nur einen ganz normalen String anzeigen. Da ist es doch überflüssig delegate zu benutzen... Ist Qt so beschränkend, dass ich nicht einfach nach alternativen Daten sortieren kann, ohne großen Aufwandt?
was genau meinst du mit "sortiert falsch"?
(http://doc.trolltech.com/4.6/qtablewidget.html#details)
(http://doc.trolltech.com/4.6/qtablewidget.html#details)
Statt direkt ein TableWidget zu nehmen, könntest du dir ein QStandardItemModel zusammenbauen, das als Model eines QSortFilterProxyModels setzen und das in nem QTableView anzeigen lassen ...f you want to enable sorting in your table widget, do so after you have populated it with items, otherwise sorting may interfere with the insertion order
Sortiert falsch, weil dein QTableWidget immer nur nach der Qt::DisplayRole sortiert. Der Konstruktor setzt die Qt::UserRole korrekt und du schreibst was ins die UserRole die aber niemanden interessiert da es mE keinen Weg gibt dem QTableWidget zu sagen er soll diese Rolle als Sortier-Rolle nehmen .... höchstens durch Ableiten und selbst implementieren ...dazedly hat geschrieben:Code: Alles auswählen
QTableWidgetItem *priceTableWidgetItem = new QTableWidgetItem(QString::number(therapy->getPrice(), 'f', 2).append(QString::fromUtf8("¤"))); priceTableWidgetItem->setData(Qt::UserRole, therapy->getPrice());
Sortiert richtig und zeigt falsch an weil du erst das richtige in die Qt::DisplayRole reinschreiben lässt (via Konstruktor) und dann manuell überschreibst (via setData) damit sortiert er nach der DisplayRole in der nun für deine Verhältnisse das Richtige drin stehtCode: Alles auswählen
QTableWidgetItem *priceTableWidgetItem = new QTableWidgetItem(QString::number(therapy->getPrice(), 'f', 2).append(QString::fromUtf8("¤"))); priceTableWidgetItem->setData(Qt::DisplayRole, therapy->getPrice());
Was ist hieran Kanone und Spatzen? Das Proxy dazwischen zu stecken sind keine 10 Zeilen ... und du erhältst damit die Möglichkeit nach Spalten, nach verschiedenen Qt:Types und sonstiges zu sortieren ... und zu Filtern ...
Code: Alles auswählen
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtGui>
#include <QtCore>
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
public slots:
void sortUserRole() { proxy->setSortRole(Qt::UserRole); }
void sortDisplayRole() { proxy->setSortRole(Qt::DisplayRole); }
private:
QSortFilterProxyModel * proxy; //// 1 /////////////////////////////////////////
QStandardItemModel * model;
QTableView * view;
};
#endif // MAINWINDOW_HCode: Alles auswählen
#include "mainwindow.h"
#include <algorithm>
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
// amount of items
const int COUNT=3000;
// create view
view = new QTableView;
view->setSortingEnabled(true); //// 0 ( you need to set this anyway) /////////////////////////////////////////
// create model
model = new QStandardItemModel;
model->setRowCount(COUNT);
model->setColumnCount(1);
// create filter/sort proxy
proxy = new QSortFilterProxyModel; //// 2 /////////////////////////////////////////
// randomize prices
srand(time(0));
// some values
QVector<double> ms;
ms.reserve(COUNT);
// create prices
for (int i=0; i < COUNT; ++i)
{
ms.push_back( rand()%100000 / 1000.0 );
}
// randomize further by shuffling
std::random_shuffle(ms.begin(),ms.end());
// create items
for(int rowNr=0; rowNr<COUNT; rowNr++)
{
// one row
QStandardItem *sub = new QStandardItem;
// display role value (qstring !!)
sub->setData(QVariant(QString::number(ms.back(),' ',2)+QString::fromUtf8(" ¤")), Qt::DisplayRole);
// user role value (double !!)
sub->setData(QVariant(ms.back()),Qt::UserRole);
// insert it
model->setItem(rowNr,0,sub);
// remove value from vector
ms.pop_back();
}
// use standard model als model for proxy
proxy->setSourceModel(model); //// 3 /////////////////////////////////////////
proxy->setSortRole(Qt::DisplayRole); //// still 3 (thats the default, just uttering it for your convenience) /////////////////////////////////////////
// use proxy as model for view
view->setModel(proxy); //// still 3 (you need to set one datasource anyway)
// sort buttons
QPushButton * pb1 = new QPushButton("Sort after Qt::DisplayRole");
connect(pb1,SIGNAL(clicked()),this,SLOT(sortDisplayRole()));
QPushButton * pb2 = new QPushButton("Sort after Qt::UserRole");
connect(pb2,SIGNAL(clicked()),this,SLOT(sortUserRole()));
QWidget * w = new QWidget;
QVBoxLayout * l = new QVBoxLayout(w);
l->addWidget(pb1);
l->addWidget(pb2);
l->addWidget(view);
setCentralWidget(w);
}
Zuletzt geändert von padreigh am 5. Oktober 2010 08:29, insgesamt 1-mal geändert.
Ich habe nur gemacht was upsala vorschlug:dazedly hat geschrieben: Ich verstehe es endlich!
Selber machen wäre edukativ gesehen vielleicht besser gewesen. Ich hab bloss deine Problembeschreibung auf ein kleines Beispiel runtergebrochen, sowas nennt sich Minimalbeispiel ... das selbst zu machen solltest du dir vielleicht angewöhnen. Wenn du sowas postest dann kann dir schneller geholfen werden ... und meist lernst du beim Erstellen des Minimalbeispiels mehr als du denkst - und manchmal/meist löst sich dein Problem von alleine weil du bemerkst wo es liegt, oder feststellst das die Stelle die du im Auge hattest damit überhaupt nix damit zu tun hat. Im Idealfall lokalisierst du den Fehler anderswo und wenn der dann nicht lösbar ist, kannst du zumindest bessere Fragen im Forum stellen ...... [Mund,fusslig,...]upsala hat geschrieben: Hinterlege [...] deine Zahlen mit data() in einer anderen Role.
//edit: -v,
Ich hab dein Beispiel jetzt nachgearbeitet. Ich hab nicht einfach Copy+Paste gemacht, sondern mir alles genau angesehen. So habe ich wieder ein Stückweit etwas gelernt
Nur muss ich jetzt feststellen, dass mir nur für eine richtige Sortierung viel Kompfort verloren geht, da Die meisten Funktionen nicht mehr verfügbar sind, welche ich noch mit meinem QTableWidget hatte.
In meinen Augen ist diese Lösung immernoch nicht optimal, weil ein zweiter Datensatz offensichtlich so einfäch wäre
In meinen Augen ist diese Lösung immernoch nicht optimal, weil ein zweiter Datensatz offensichtlich so einfäch wäre