[gelöst] QTableView QTableModel Gliederung
[gelöst] QTableView QTableModel Gliederung
Hallo Leute,
ich brauche einen kleinen Denkanstoß:
Ich habe Daten in einer SQL-Tabelle, die ich mit Hilfe von QTableModel und QTableView darstelle.
Wie kann ich die Darstellung der Daten gliedern? Zumindest will ich zwischen einzelnen Datenbereichen Leerzeilen haben, eigentlich sogar noch eine Art Überschrift.
Ich frage mich gerade, ob ich versuchen soll, QTableView so anzupassen, dass nur die Darstellung der Daten so ist, wie ich es möchte oder ob man sowas realisiert durch "falsche" Datensätze, also zusätzliche Zeilen in der dargestellten Datenbank, die bei allen Arbeiten mit den Daten als Ausnahmen berücksichtigt werden müssen.
Wenn jemand eine Idee zu dieser eher grundsätzlichen Frage hat, freue ich mich über Hinweise!
Grüße,
gk_17
ich brauche einen kleinen Denkanstoß:
Ich habe Daten in einer SQL-Tabelle, die ich mit Hilfe von QTableModel und QTableView darstelle.
Wie kann ich die Darstellung der Daten gliedern? Zumindest will ich zwischen einzelnen Datenbereichen Leerzeilen haben, eigentlich sogar noch eine Art Überschrift.
Ich frage mich gerade, ob ich versuchen soll, QTableView so anzupassen, dass nur die Darstellung der Daten so ist, wie ich es möchte oder ob man sowas realisiert durch "falsche" Datensätze, also zusätzliche Zeilen in der dargestellten Datenbank, die bei allen Arbeiten mit den Daten als Ausnahmen berücksichtigt werden müssen.
Wenn jemand eine Idee zu dieser eher grundsätzlichen Frage hat, freue ich mich über Hinweise!
Grüße,
gk_17
Zuletzt geändert von gk_17 am 21. Januar 2011 17:02, insgesamt 2-mal geändert.
das Verwenden eines ProxyModel entspräche ja der Erstellung einer speziellen Datenbank, wenn ich das richtig verstanden habe, zumindest wird QTableView es so sehen, richtig?
Ich glaube auch alles zu kennen, was in der Qt-Dokumentation zu QProxyModel und QTableView steht, leider habe ich immer noch keine Idee, wie ich das umsetze. Vielleicht hilft es, wenn ich ein weiteres Darstellungsproblem beschreibe? Ich will neben den SQL-Daten eine weitere Spalte anzeigen, die z.B. die Summe einiger SQL-Spalten enthält. Bisher erstelle ich eine neue erweiterte SQL-Tabelle im Arbeitsspeicher und gebe die ans QTableModel.
Wie kann ich dieses Problem eleganter lösen? Ich vermute, auch hier kann ich wieder das ProxyModel einsetzen, aber welche Methoden genau muss ich mir angucken?
Grüße,
gk_17
Ich glaube auch alles zu kennen, was in der Qt-Dokumentation zu QProxyModel und QTableView steht, leider habe ich immer noch keine Idee, wie ich das umsetze. Vielleicht hilft es, wenn ich ein weiteres Darstellungsproblem beschreibe? Ich will neben den SQL-Daten eine weitere Spalte anzeigen, die z.B. die Summe einiger SQL-Spalten enthält. Bisher erstelle ich eine neue erweiterte SQL-Tabelle im Arbeitsspeicher und gebe die ans QTableModel.
Wie kann ich dieses Problem eleganter lösen? Ich vermute, auch hier kann ich wieder das ProxyModel einsetzen, aber welche Methoden genau muss ich mir angucken?
Grüße,
gk_17
Ungefähr so:
Code: Alles auswählen
class MyModel : public QAbstractTableModel
{
void setModel(QAbstractItemModel *m) : myModel(m);
int rowCount() { return myModel->rowCount(); };
int columnCount() { return myModel->columnCount()+1; };
QVariant data(index, role) {
if (index.count()<columnCount()) {
return myModel->data(myModel->index(index.row(), index.column()), role);
} else {
// Summe berechnen
return summe;
}
}
};
Vielen Dank,
das war genau der richtige Tipp!
Allerdings komme ich schon wieder nicht weiter.
Die data()-Methode meines ProxyModels liefert eine Leerzeile, wenn QTableView nach z.B. Zeile 5 fragt, wenn QTableView nach den Daten für Zeile 6 fragt, werden die Daten der Zeile 5 geliefert. Implementiert habe ich es wie oben vorgeschlagen.
Leider fällt jetzt hinten eine Zeile weg, d.h. es werden nur so viele Zeilen angezeigt, wie ursprünglich Daten vorhanden waren.
Also habe ich bei meinem ProxyModel die Methode rowCount() überschrieben und liefere jetzt rowCount()+1 zurück. Nun gibt es die richtige Anzahl Zeilen in QTableView, aber die letzte Zeile ist leer und hat die Zeilennummer 0, eigentlich sollten hier Daten enthalten sein.
Was muss ich noch anpassen, damit es funktioniert?
Grüße,
gk_17
das war genau der richtige Tipp!
Allerdings komme ich schon wieder nicht weiter.
Die data()-Methode meines ProxyModels liefert eine Leerzeile, wenn QTableView nach z.B. Zeile 5 fragt, wenn QTableView nach den Daten für Zeile 6 fragt, werden die Daten der Zeile 5 geliefert. Implementiert habe ich es wie oben vorgeschlagen.
Leider fällt jetzt hinten eine Zeile weg, d.h. es werden nur so viele Zeilen angezeigt, wie ursprünglich Daten vorhanden waren.
Also habe ich bei meinem ProxyModel die Methode rowCount() überschrieben und liefere jetzt rowCount()+1 zurück. Nun gibt es die richtige Anzahl Zeilen in QTableView, aber die letzte Zeile ist leer und hat die Zeilennummer 0, eigentlich sollten hier Daten enthalten sein.
Was muss ich noch anpassen, damit es funktioniert?
Grüße,
gk_17
Hm, das wird schwierig, aber ich versuchs mal.
Ich habe WeightsTableModel von QSqlQueryModel abgeleitet, keine weiteren wichtigen Methoden überschrieben.
Diesem TableModel ordne ich eine SQL-Tabelle zu, die sagen, wir 10 Zeilen enthält.
Das TableModel verbinde ich mit einer von QTableView abgeleiteten Klasse:
Alles genau, wie in den Qt-Tutorials beschrieben. Es werden genau 10 Zeilen angezeigt.
Nun gibt es ein ProxyModel:
Hier ist noch nichts überschrieben, es wird einfach nur zwischengeschaltet und alle 10 Zeilen werden angezeigt wie vorher.
Jetzt soll nach der 5. Zeile eine Leerzeile eingefügt werden, also überschreibe ich die data()-Methode de Proxy-Klasse:
Nun werden immer noch 10 Zeilen angezeigt, aber die 5. Zeile ist leer.
Jetzt überschreibe ich die rowCount()-Methode:
Die TableView zeigt 11 Zeilen, die 5. ist leer, die letzte aber auch, und sie hat die Zeilennummer 0. Als anfänglich alle 10 Datenzeilen angezeigt wurden, hatten diese die Nummern 1 bis 10. Jetzt ist Zeile 5 leer, Zeile 6 bis 10 enthalten die Daten von Originalzeile 5 - 9, Zeile 11 aber leider nicht die Daten von Originalzeile 10, sondern sie ist leer und hat zudem noch die falsche Zeilennummer 0.
Ich hoffe das beschreibt mein Problem etwas genauer. Es gibt sicher irgendeine Methode, die ich auch noch abändern muss, aber leider finde ich in der Qt-Dokumentation keine Hinweise.
By the way: ihr, die ihr mir weiterhelfen könnt: woher habt ihr das Wissen, gibt es Bücher, die mehr zu dem Model-View-Konzept von Qt schreiben als das Standardbuch von Blanchette/Summerfield?
Grüße,
gk_17[/code]
Ich habe WeightsTableModel von QSqlQueryModel abgeleitet, keine weiteren wichtigen Methoden überschrieben.
Code: Alles auswählen
class WeightsTableModel : public QSqlQueryModel
{
Q_OBJECT
public:
WeightsTableModel(QObject* parent);
~WeightsTableModel();
Qt::ItemFlags flags(const QModelIndex &index) const;
};Das TableModel verbinde ich mit einer von QTableView abgeleiteten Klasse:
Code: Alles auswählen
class WeightsTableView : public QTableView
{
Q_OBJECT
public:
WeightsTableView(QWidget* parent);
~WeightsTableView();
};Nun gibt es ein ProxyModel:
Code: Alles auswählen
class WeightsGroupingProxyModel : public QSortFilterProxyModel
{
public:
WeightsGroupingProxyModel(QObject* parent);
~WeightsGroupingProxyModel();
};Jetzt soll nach der 5. Zeile eine Leerzeile eingefügt werden, also überschreibe ich die data()-Methode de Proxy-Klasse:
Code: Alles auswählen
QVariant WeightsGroupingProxyModel::data(const QModelIndex &index, int role) const
{
if(index.row() == 5)
{
QVariant value;
return value;
}
else if(index.row() > 5)
{
return QSortFilterProxyModel::data(this->index(index.row() + 1, index.column()), role);
}
else
{
return QSortFilterProxyModel::data(this->index(index.row(), index.column()), role);
}
}Jetzt überschreibe ich die rowCount()-Methode:
Code: Alles auswählen
int WeightsGroupingProxyModel::rowCount(const QModelIndex& parent) const
{
return QSortFilterProxyModel::rowCount() +1;
}Ich hoffe das beschreibt mein Problem etwas genauer. Es gibt sicher irgendeine Methode, die ich auch noch abändern muss, aber leider finde ich in der Qt-Dokumentation keine Hinweise.
By the way: ihr, die ihr mir weiterhelfen könnt: woher habt ihr das Wissen, gibt es Bücher, die mehr zu dem Model-View-Konzept von Qt schreiben als das Standardbuch von Blanchette/Summerfield?
Grüße,
gk_17[/code]
Code: Alles auswählen
QVariant WeightsGroupingProxyModel::data(const QModelIndex &index, int role) const
{
// bis einschl. 4 alles normal
if (index.row() < 5)
return QSortFilterProxyModel::data(this->index(index.row(), index.column()), role);
// bei 5 ne Zusatzzeile
if(index.row() == 5)
return QVariant();
// über 5 die Daten aus einer Zeile drunter
if(index.row() > 5)
return QSortFilterProxyModel::data(this->index(index.row() - 1, index.column()), role);
}
Zuletzt geändert von padreigh am 20. Januar 2011 20:57, insgesamt 1-mal geändert.
Code: Alles auswählen
MyProxyModel::MyProxyModel(QObject *parent)
: QAbstractTableModel(parent), m_source(0)
{
}
MyProxyModel::~MyProxyModel()
{
}
void MyProxyModel::setSource(QAbstractItemModel *source)
{
m_source=source;
reset();
}
int MyProxyModel::columnCount(const QModelIndex &/*parent*/) const
{
return m_source ? m_source->columnCount() : 0;
}
int MyProxyModel::rowCount(const QModelIndex &/*parent*/) const
{
return m_source ? m_source->rowCount()+1 : 0;
}
QVariant MyProxyModel::data(const QModelIndex &index, int role) const
{
if (m_source && index.isValid()) {
if (index.row()<5) {
return m_source->data(m_source->index(index.row(), index.column()), role);
} else if (index.row()>5) {
return m_source->data(m_source->index(index.row()-1, index.column()), role);
} else {
}
}
return QVariant();
}
Qt::ItemFlags MyProxyModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags flags;
if (m_source && index.isValid()) {
if (index.row()<5) {
flags=m_source->flags(m_source->index(index.row(), index.column()));
} else if (index.row()>5) {
flags=m_source->flags(m_source->index(index.row()-1, index.column()));
} else {
}
}
return flags;
}
QVariant MyProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (!m_source) return QVariant();
if (orientation==Qt::Vertical) {
if (section<5) {
return m_source->headerData(section, orientation, role);
} else if (section>5) {
return m_source->headerData(section-1, orientation, role);
} else {
return QVariant();
}
}
return m_source->headerData(section, orientation, role);
}
int MyProxyModel::columnCount(const QModelIndex &/*parent*/) const
{
return m_source ? m_source->columnCount() : 0;
}
int MyProxyModel::rowCount(const QModelIndex &/*parent*/) const
{
return m_source ? m_source->rowCount()+1 : 0;
}
QVariant MyProxyModel::data(const QModelIndex &index, int role) const
{
if (m_source && index.isValid()) {
if (index.row()<5) {
return m_source->data(m_source->index(index.row(), index.column()), role);
} else if (index.row()>5) {
return m_source->data(m_source->index(index.row()-1, index.column()), role);
} else {
}
}
return QVariant();
}
Qt::ItemFlags MyProxyModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags flags;
if (m_source && index.isValid()) {
if (index.row()<5) {
flags=m_source->flags(m_source->index(index.row(), index.column()));
} else if (index.row()>5) {
flags=m_source->flags(m_source->index(index.row()-1, index.column()));
} else {
}
}
return flags;
}
QVariant MyProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (!m_source) return QVariant();
if (orientation==Qt::Vertical) {
if (section<5) {
return m_source->headerData(section, orientation, role);
} else if (section>5) {
return m_source->headerData(section-1, orientation, role);
} else {
return QVariant();
}
}
return m_source->headerData(section, orientation, role);
}