Seite 1 von 2
[gelöst] QTableView ineffizient
Verfasst: 25. Januar 2014 14:42
von lespaul
Hallo Leute,
ich habe eine Binäre Datei --> ca. 1-2 Megabytes, diese hat viele Datensätze (Datum+Messwerte).
Ein Datensatz sind immer 32 Bytes ( := 8 Bytes (Datum+Uhrzeit) + 24 * Byte einzelne Messwerte), also zB:
00 00 00 00 C0 E4 D3 40 02 07 0A 11 12 29 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FE
Byte 0-7 = Datum (00 00 00 00 C0 E4 D3 40)
Byte 8-31 einzelne Byte-Messwerte (02 07 0A 11 12 29 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FE)
Ich möchte die Messwerte in einer Tabelle ausgeben, ein Datensatz entspricht eine Zeile. Beispiel oben etwa:
| Datum | 1. Wert | 2.Wert | 3.Wert | ... | 23.Wert | 24.Wert |
...
| 24.11.2013 | 2 | 7 | 10 | 17 | 41 | 255 | ... | 0 | 254 |
...
Bis jetzt habe ich eine QTableWidget, in diese füge ich alle einzelnen Felder einzeln hinzu (mittels 2fach verschachtelter for-Schleife). Das kommt mir sehr ineffizient vor.. Wäre es mit einem Model/View effizienter?
Thnx und mfg Lespaul
Re: QTableView ineffizient
Verfasst: 25. Januar 2014 18:16
von sigvdr
Aber sicher doch!
Mit QTableWidget musst du den gesamten Datenbestand in die "Tabellenstruktur" hineinkopieren und damit viele viele QTableWidgetItems anlegen.
QTableView fordert von seinem Model immer nur die gerade benötigten sichtbaren Daten.
Anmerkung: Im Model müssen die Daten auch nicht in einer "Tabellenstruktur" vorhanden sein.
Beispiel:
http://www.qtforum.de/forum/viewtopic.p ... 168#p77179
Gruß Sig
Re: QTableView ineffizient
Verfasst: 29. Januar 2014 21:17
von lespaul
Vielen Dank für die Antwort. Ich bin dabei mein Projekt auf das Model/View Konzept umzustellen. Dazu hätte ich eine Frage:
1.)
Ein Datensatz ist ja folgendermaßen (Datum Wert1 Wert2 ... Wert24). Ich übernehme das Beispiel bei qt-project, dort wurden jede Zeile in eine QList<QVariant> gepackt. Bei mir foglen für einen Datensatz nach dem Datum 24 unsigned char Werte (0-255). Diese 8bittigen Werte als QVariant und dann bei 10000 Datensätzen .. hmmm ich weiss ehrlich gesagt grad nicht, wie ein QVariant auf dem Arbeitsspeicher aussieht? Hängt vermutlich vom Inhalt ab?
Code: Alles auswählen
//..
QVariant(QChar c)
QVariant(const QDate & val)
//..
Wenn ich eine char (8bit) reinpacken würde, würde diese dort dann auch 8bit abgespeichert?
Würdet ihr eine eigene Datenstruktur für einen Datensatz schreiben a la
Code: Alles auswählen
class EinDatensatz
{
//...
private:
QDate ds_datum;
quint8[24] ds_werte;
}
?
Macht es Sinn, dann später
mit wohlmöglich über 10000 Zeilen zu verwenden?? Bin grad verwirrt..
Re: QTableView ineffizient
Verfasst: 30. Januar 2014 11:09
von RHBaum
Dein Problem ist, das Du "im ganzen" denkst ....
Das heisst du willst alle infos bevor du das Model befüllst.
Und genau das ist der Vorteil des Model View Konzepts's, daß du genau das nicht brauchst.
Eigentlich spricht man von MVC - Model View Conntroller .... nur hier ist model + View gleichzeitig der Controller
vereinfacht erklärt: Das View fragt das Model, was zu zeigen ist. Dann zeigt das View nur einen Bestimmten bereich der Gesamten Daten an, wenn die daten so gross sind, das sie nicht aufs mal dargestellt werden.
Dafür informiert das Model den view, wenn sich was geändert hat. Das View entscheidet dann, ob was zu tun ist, und fragt die relevanten daten bei Bedarf neu ab ...
ALso das einzige was das Model im "Vorfeld" wissen muss und relativ haeufig abgefragt wird, ist die Struktur, und die Dimension (Zeilen / Spalten anzahl) .... und das auch nicht immer, models können auch "wachsen"
Alles andere fragt das ding "bei Bedarf".
WIllst du ein performantes Model auf Dateibasis, wirst du die datei nicht komplett auslesen.
du wirst deinem model einfach das datei-Handle geben ....
Die struktur gibst du selber vor. Ich nehm an es wird was mit fixen Spalten und variablen Zeilen.
Du hasst ne fixe Dateistruktur ohne variablen Anteil (aka Strings mit variabler Länge)?
Dann ists recht einfach ... Die Anzahl der Zeilen bekommst dann aus der dateigroesse.
die Abfrage bestimmter elemente (index) bekommst ueber die File Posi - einfach zeiger positionieren - auslesen - in Rueckgabe verpacken. Vielleicht bissi cachen für die Performance
Hasst du variable anteile, musst du einmal komplett scannen und Ne index liste erstellen ... also sowas wie: Datensatz 1264 beginnt an file Posi 129047 ....
Damit kennst dann auch die Zeilenzahl .... und zugriff geht dann halt nur ueber die Zwischenliste.
Wird diese Zwischenliste zu groß, kannst die auch in ner Temp Datei "auslagern" .....
Mit Multithreading KnowHow kannst das Model dann auch so bauen, das alle funktionen aus dem GUI Thread flott zurueck kehren, Aka das View sofort angezeigt wird, und das Model parralel aufgebaut wird, aka mit der Zeit befüllt ...
Und schon brauchst dir keinen kopf machen, wie gross deine Dateien sind und was alles in den Arbeitsspeicher passt .....
und alle finden toll das dein View sofort was anzeigt und nicht erst mal zig min daten einliest und umherswappt ^^
Ciao ...
Re: QTableView ineffizient
Verfasst: 30. Januar 2014 12:57
von lespaul
Vielen Dank für deine Antwort!
RHBaum hat geschrieben:WIllst du ein performantes Model auf Dateibasis, wirst du die datei nicht komplett auslesen.
du wirst deinem model einfach das datei-Handle geben ....
Das hört sich super an, ich wollte auch auf sowas hinaus..
RHBaum hat geschrieben:Die struktur gibst du selber vor. Ich nehm an es wird was mit fixen Spalten und variablen Zeilen. Du hasst ne fixe Dateistruktur ohne variablen Anteil (aka Strings mit variabler Länge)?
Dann ists recht einfach ... Die Anzahl der Zeilen bekommst dann aus der dateigroesse.
Richtig! Beispielsweise :
Code: Alles auswählen
QByteArray myPayload(filehandler.readAll());
long filesize = myPayload.size(); // Dateigröße Bsp. 230400 bytes
int ds_size = 32; // pro Datensatz
long ds_count = filesize / ds_size; // ergäbe 7200 Zeilen an Datensätzen
// alle Datensätze der Reihe nach auslesen
for (long i = 0; i < ds_count; i++)
{
QByteArray ein_ds = myPayload.mid(i*32, 32);
}
RHBaum hat geschrieben:
die Abfrage bestimmter elemente (index) bekommst ueber die File Posi - einfach zeiger positionieren - auslesen - in Rueckgabe verpacken. Vielleicht bissi cachen für die Performance
Das ist doch das was du meinst, und genau das was ich brauche
http://doc.qt.digia.com/qq/qq15-models. ... tfilemodel ? Ich werd mich gleich heut abend dran setzten und freu mich schon

Re: QTableView ineffizient
Verfasst: 30. Januar 2014 13:18
von RHBaum
ist die dynamische Variante .... weil keine binaere fixe datenstruktur.
Die muessen auf die Lineendings parsen und sich die Posi liste halten ... (mutable QVector<int> offsets;)
das alles brauchst du gar ned ...
in der data(const QModelIndex & index, int role) methode kannst dir die FilePosi einfach ala
index.row() * DATASIZE berechnen und da die daten auslesen ...
dein model wär viel einfacher als das da besprochene ...
Nur als Tipp:
Byte 0-7 = Datum (00 00 00 00 C0 E4 D3 40)
Byte 8-31 einzelne Byte-Messwerte (02 07 0A 11 12 29 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FE)
Code: Alles auswählen
struct DataEntryT
{
quint64 timestamp;
quint8 data[24];
};
dank 8 ByteAllignment bietet sich sowas als Type förmlich an
Ciao ...
Re: QTableView ineffizient
Verfasst: 1. Februar 2014 00:48
von lespaul
Supi, funzt sowit prima.
Hab nur noch ne kleine Frage zu den Widgets:
QMainWindow -> QWidget -> QVBoxLayout -> QTabWidget -> QWidget -> QVBoxLayout -> ..
|
Wenn ich das Hauptfenster maximiere, bleibt das QTabWidget unskaliert.. Jemand eine Idee?
Re: QTableView ineffizient
Verfasst: 1. Februar 2014 14:02
von sigvdr
Das TabWidget durch maximumSize() begrenzt, oder QSizePolicy::fixed.
Gruß Sig
Re: QTableView ineffizient
Verfasst: 2. Februar 2014 15:54
von lespaul
sigvdr hat geschrieben:Das TabWidget durch maximumSize() begrenzt, oder QSizePolicy::fixed
Auch wenn ich Expanging einstelle, bleibt es so unglkücklich.
Desweiteren sind auch der Inhlat meiner Tabellenfelder linksbündig. Gegoogelt könnte ich die Alginment einstellen a la:
Code: Alles auswählen
QVariant MeinModel::data ( const QModelIndex & index, int role ) const
{
if (role == Qt::TextAlignmentRole)
return Qt::AlignCenter;
//..
}
Pustekuchen, will bei mir nicht..

Re: QTableView ineffizient
Verfasst: 2. Februar 2014 17:02
von sigvdr
Code: Alles auswählen
QVariant MeinModel::data ( const QModelIndex & index, int role ) const
{
if (role == Qt::TextAlignmentRole)
return Qt::AlignCenter;
//..
}
Richtig! Exakt genau so muss das gehen.
Gruß Sig
Re: QTableView ineffizient
Verfasst: 2. Februar 2014 17:55
von lespaul
sigvdr hat geschrieben:Richtig! Exakt genau so muss das gehen.
Weder
noch
machen den Inhalt meiner Tabelle mittig. Die Spaltenüberschirften sind mittig, mir geht es aber mehr um den eigentlichen Tabelleninhalt..
Re: QTableView ineffizient
Verfasst: 3. Februar 2014 07:01
von sigvdr
Wie schon gesagt, genau so muss es gehen. Falls das bei dir nicht so ist, dann liegt das an einem anderen Fehler, den es zu finden gilt.
Zeig uns mal den Code von data(...) komplett.
Gruß sig
Re: QTableView ineffizient
Verfasst: 3. Februar 2014 15:53
von lespaul
Code: Alles auswählen
QVariant MeasureTableModel::data(const QModelIndex &index, int role) const
{
// Grenzen sprengen
if (!index.isValid()
|| index.row() > record_count
|| index.row() < 0 || role != Qt::DisplayRole)
return QVariant();
if (role == Qt::TextAlignmentRole) return Qt::AlignHCenter;
// Open File
if (!importFile->open(QIODevice::ReadOnly)) return QVariant();
importFile->seek( index.row()*RECORD_SIZE );
QByteArray bytes = importFile->read(RECORD_SIZE);
importFile->close();
if (bytes.size() != RECORD_SIZE) return QVariant();
return QVariant(MeasureValues::getSetAsVariant(bytes).at(index.column()));
}
Re: QTableView ineffizient
Verfasst: 3. Februar 2014 16:24
von MichaelS
Aufgrund dieser Anweisung kommt Dein Programm gar nicht mehr zur Formatierung.
Gruß Michael
Re: QTableView ineffizient
Verfasst: 3. Februar 2014 16:42
von lespaul
Auskommentiert oder gelöscht
Habe ich nun lauter Checkboxen in jedem Feld in der Tabelle?
