[gelöst] rowCount() liefert immer 256

Alles rund um die Programmierung mit Qt
Antworten
gk_17
Beiträge: 37
Registriert: 4. Oktober 2009 19:20

[gelöst] rowCount() liefert immer 256

Beitrag von gk_17 »

Moin liebes Forum,

ich habe vermutlich ein Problem mit der Implementierung einer rowCount()-Methode.
Mein Programm zeigt Daten einer SQLite-Tabelle in einer TableView an und beschränkt die Datenmenge manchmal auf 256 Zeilen.

Vereinfacht mache ich folgendes:

1. erzeuge Objekt vom Typ WeightsTableModel, abgeleitet von QSqlQueryModel, verknüpfe mit Daten
2. erzeuge Objekt WeightsSortFilterProxyModel, abgeleitet von QSortFilterProxyModel (ohne selbst hinzugefügten Code), per setSourceModel() wird das WeightsTableModel verknüpft
4. meiner WeightsTableView(), abgeleitet von QTableView, wird per setModel() das WeightsSortFilterProxyModel übergeben

soweit funktioniert alles, alle 800 Zeilen einer Tabelle werden dargestellt.

Jetzt kommt der Punkt 3:
3. erzeuge Objekt WeightsGroupingProxyModel, abgeleitet von QAbstractTableModel, setze wie oben das WeightsSortFilterProxyModel als sourceModel und übergebe an WeightsTableView, jetzt stellt die TableView nur noch 256 Zeilen dar.
Meine rowCount-Methode in WeightsGroupingProxyModel sieht so aus:

Code: Alles auswählen

int WeightsGroupingProxyModel::rowCount(const QModelIndex & parent) const
{
	return sourceModel->rowCount();
}
Ich bin etwas ratlos, wie die rowCount()-Methode mit der TableView zusammen spielt und ob ich irgendwo was vergessen habe. Zum Testen habe ich bei der Erstellung der einzelnen Model-Objekte nach Schritt 1, 2 und 3 jeweils per qDebug() das Ergebnis von rowCount() ausgeben lassen, und es wird immer 256 zurückgeliefert, auch schon bei den ersten beiden TableModels, die ja eigentlich richtig funktionieren.

Hat jemand einen kleinen Gedankenanstoß für mich?
Grüße,
Gernot
Zuletzt geändert von gk_17 am 12. Juni 2011 11:00, insgesamt 1-mal geändert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Ich weiss jetzt nicht von welchem Typ sourceModel im Codebeispiel ist, aber rowCount() von QSqlQueryModel hat folgende Signatur:

Code: Alles auswählen

QSqlQueryModel::rowCount ( const QModelIndex & parent = QModelIndex() ) const
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
gk_17
Beiträge: 37
Registriert: 4. Oktober 2009 19:20

Beitrag von gk_17 »

sourceModel war vom Typ QAbstractItemModel, von dem mein WeightsSortFilterProxyModel letztendlich auch abgeleitet ist. Dieses WeightsSortFilterProxyModel wird mittels der setSource()-Methode des WeightsGroupingProxyModel in einem Objekt diesen Typs gespeichert.

Die rowCount()-Methode ist genau wie oben deklariert und meiner Meinung nach auch richtig implementiert (siehe Ausgangspost).

Ich hab jetzt mal den Typ von sourceModel in WeightsGroupingProxyModel von QAbstractItemModel auf WeightsSortFilterProxyModel geändert, ohne Auswirkungen.

Ich wundere mich ja auch, warum eine Ausgabe von rowCount() des obersten Models (WeightsTableModel) direkt nach dessen Initialisierung 256 zurück gibt, aber anschließend die View alle 800 Zeilen anzeigt. Hab ich da irgendwas falsch verstanden?

Und ich habe auch mal das WeightsSortFilterProxyModel aus der Kette der Models weggelassen. Also nur 1., 3. und 4., leider auch ohne Auswirkungen.
gk_17
Beiträge: 37
Registriert: 4. Oktober 2009 19:20

Beitrag von gk_17 »

ich habe noch etwas ausprobiert: ich habe WeightsGroupingProxyModel auf den minimal nötigen Code reduziert, und es geht immer noch nicht. Dafür kann ich den Quellcode posten, er ist jetzt sehr übersichtlich.

weightsgroupingproxymodel.h

Code: Alles auswählen

#ifndef WEIGHTSGROUPINGPROXYMODEL_H
#define WEIGHTSGROUPINGPROXYMODEL_H

#include <QAbstractTableModel>

class WeightsGroupingProxyModel : public QAbstractTableModel
{
public:
    WeightsGroupingProxyModel(QObject* parent);
    ~WeightsGroupingProxyModel();
    
    int 						columnCount(const QModelIndex & parent = QModelIndex()) const;
    int 						rowCount(const QModelIndex & parent = QModelIndex()) const;
    QVariant 					data(const QModelIndex &index, int role = Qt::DisplayRole) const;
    void 						setSource(QAbstractItemModel *source);
    
    QAbstractItemModel*			sourceModel;    
};

#endif
weightsgroupingproxymodel.cpp

Code: Alles auswählen

#include "weightsgroupingproxymodel.h"
#include <QVariant>

WeightsGroupingProxyModel::WeightsGroupingProxyModel(QObject* parent) 
: QAbstractTableModel(parent), sourceModel(0)
{
}

WeightsGroupingProxyModel::~WeightsGroupingProxyModel()
{
}

int WeightsGroupingProxyModel::columnCount(const QModelIndex & parent) const
{
	return sourceModel->columnCount();
}

int WeightsGroupingProxyModel::rowCount(const QModelIndex & parent) const
{
	return sourceModel->rowCount();
}

QVariant WeightsGroupingProxyModel::data(const QModelIndex &index, int role) const
{
  	return sourceModel->data(sourceModel->index(index.row(), index.column()), role);
}
Die Klasse funktioniert insoweit, als dass sie die Daten der vorgeschalteten Models durchreicht, aber eben leider nur maximal 256 Zeilen :( Wenn ich in rowCount() implementiere: return 500;, dann hat die TableView 500 Zeilen, aber nur 256 davon sind mit Daten gefüllt.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Auch in QAbastractItemModel hat die rowCount() - Funktion eine andere Signatur... http://doc.trolltech.com/4.7/qabstracti ... l#rowCount
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
gk_17
Beiträge: 37
Registriert: 4. Oktober 2009 19:20

Beitrag von gk_17 »

Hallo Christian,
vielen Dank für Deine Hilfe, aber ich habe leider nicht die leiseste Ahnung, worauf Du mich hinweisen willst.
Ich denke, ich weiß, was eine Methodensignatur ist, aber ich kann keine Abweichung meiner Implementierung von der Vorgabe der Dokumentation finden. Und meine rowCount() wird ja aufgerufen und funktioniert perfekt bis 256 Zeilen, nur wenn die Daten aus mehr Zeilen bestehen, gibt es das Problem.
Gib mir bitte noch einen weiteren Hinweis, was Du meinst ;)

Grüße,
Gernot
ScyllaIllciz
Beiträge: 200
Registriert: 9. Juli 2010 19:31

Beitrag von ScyllaIllciz »

Ich glaube Er will darauf hinweisen

Code: Alles auswählen

return sourceModel->columnCount(); 
;-)
gk_17
Beiträge: 37
Registriert: 4. Oktober 2009 19:20

Beitrag von gk_17 »

Hm, ok. Die rowCount()-Methode genau so zu überschreiben habe ich irgendwo aufgeschnappt. Wenn ich die rowCount()-Methode des vorgeschalteten TableModels aufrufe, kann ich natürlich auch parent übergeben, aber es ändert nichts.

Jetzt sieht die Methode also so aus:

Code: Alles auswählen

int WeightsGroupingProxyModel::rowCount(const QModelIndex & parent) const
{
   return sourceModel->rowCount(parent);
} 
Aber leider ändert das nichts am Ergebnis, immer noch nur maximal 256 Zeilen, auch wenn mehr Daten vorhanden sind.
gk_17
Beiträge: 37
Registriert: 4. Oktober 2009 19:20

Beitrag von gk_17 »

Ich habe noch etwas Interessantes gefunden.
Inzwischen arbeite ich mit einem Minimalprogramm, WeightsTableModel ist von QSqlQueryModel abgeleitet und bekommt per setQuery() nur die Verbindung mit der Datenbank, sonst keine Änderungen. Die tableView ist eine QTableView. Mein WeightsGroupingProxyModel habe ich weiter oben schon gepostet.

Mit dieser Konfiguration
WeightsTableModel -> WeightsGroupingProxyModel -> QTableView
sehe ich nur die 256 Zeilen.

Lasse ich das ProxyModel weg, also
WeightsTableModel -> QTableView
dann sehe ich nach Programmstart rechts einen vertikalen Scrollbalken, der interessanterweise genau so hoch ist wie bei der ersten Konfiguration. Wenn ich diesen Scrollbalken nun vorsichtig bis nach unten ziehe, bis Zeile 255 und der oberste Teil von 256 zu sehen ist, sieht man am verbleibenden Platz unter dem Scrollbalken, dass nur noch eine Zeile kommen kann. Wenn ich weiter ziehe, "entwischt" mir der Scrollbalken bis etwa in die Mitte der Scrollleiste und ich sehe Zeile 257 auftauchen. Das wiederholt sich so oft, bis alle 1000 Zeilen zu sehen sind.

Daraus schließe ich, dass die View irgendwie immer Teilbereiche von 256 Zeilen lädt und den Rest später nachlädt. Aber wieso macht sie das nicht mehr mit meinem eigenen ProxyModel? In der Dokumentation http://doc.qt.nokia.com/4.6/model-view- ... ssing.html steht, dass ich bei eigenen Unterklassen nur die von mir erstellten fünf Methoden brauche. Also habe ich doch alles richtig gemacht?

Hat jemand eine Idee?
gk_17
Beiträge: 37
Registriert: 4. Oktober 2009 19:20

Beitrag von gk_17 »

durch Verwendung eines eigenen TableModels tritt der Fehler nicht mehr auf, siehe auch hier
http://qtforum.de/forum/viewtopic.php?t ... highlight=
Antworten