QSqlTableModel UserRole

Alles rund um die Programmierung mit Qt
Antworten
miki11
Beiträge: 30
Registriert: 27. Oktober 2008 13:32

QSqlTableModel UserRole

Beitrag von miki11 »

Irgendwie finde ich im Netz keine Passende Beschreibung für mein Problem, vielleicht kann mir hier jemand auf die Sprünge helfen.

Ich nutze QSqlTableModel mit QSqlTableModel::OnManualSubmit und wollte vor QSqlTableModel->submitAll() die vorherige Werte in eine Log-Datei schreiben um Veränderungen zu loggen. Dafür gehe ich die Tabelle durch und suche nach isDirty Felder.
Somit weiß ich, was verändert wurde, bzw. gespeichert werden muss. Aber wie komme ich an die alte Werte?

Ich hatte mir überlegt QSqlTableModel abzuleiten und UserRole dafür zu nutzen. Wenn ich QSqlTableModel ableite, funktioniert setData irgendwie nicht mehr.

Code: Alles auswählen

class MCSqlTableModel : public QSqlTableModel {
    Q_OBJECT

public:
	MCSqlTableModel(QObject* parent = 0, QSqlDatabase db = QSqlDatabase());
	Qt::ItemFlags flags(const QModelIndex &index) const;
	bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::DisplayRole);

private:
};

Code: Alles auswählen

#include "mcsqltablemodel.h"

MCSqlTableModel::MCSqlTableModel(QObject* parent, QSqlDatabase db): QSqlTableModel(parent, db) {
}

Qt::ItemFlags MCSqlTableModel::flags(const QModelIndex& index) const {
	Qt::ItemFlags flags = QSqlQueryModel::flags(index);
	flags |= Qt::ItemIsEditable;
	return flags;
}

bool MCSqlTableModel::setData(const QModelIndex& index, const QVariant& value, int role) {
	return QSqlQueryModel::setData(index, value, role);
}
Scheinbar reicht das so nicht bei setData, um die original Funktion nachahmen zu können.

Frage:
- ist das überhaupt der richtige Weg, oder gibt es eine einfachere Möglichkeit?
- was müsste in setData stehen, damit die QSqlTableModel::setData(...) Funktion hergestellt ist? Leite ich QSqlTableModel falsch ab?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: QSqlTableModel UserRole

Beitrag von Christian81 »

Ohne weiter ins Detail zu gehen - Du leitest von QSqlTableModel ab, rufst aber direkt die Funktionen von QSqlQueryModel auf...

Code: Alles auswählen

class MCSqlTableModel : public QSqlTableModel {
...}


bool MCSqlTableModel::setData(const QModelIndex& index, const QVariant& value, int role) {
   return QSqlQueryModel::setData(index, value, role);
}
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
miki11
Beiträge: 30
Registriert: 27. Oktober 2008 13:32

Re: QSqlTableModel UserRole

Beitrag von miki11 »

Christian81 hat geschrieben:Ohne weiter ins Detail zu gehen - Du leitest von QSqlTableModel ab, rufst aber direkt die Funktionen von QSqlQueryModel auf...
L.t. Beispiele und Anleitung ist das auch so richtig. Trotzdem habe ich natürlich auch mit QSqlTableModel ausprobiert, gleiches Ergebnis.
Habe mit auch QSqlTableModel.cpp angeschaut, wie dort setData implementiert ist,hat jedoch leider auch nicht geholfen. Ich habe bei Ableitungen bis her immer ein eigenes Storage erzeugt, da das QT eigene mir nicht passte, jetzt wollte ich das mal mit der QT Storage versuchen, aber scheinbar scheitere ich bei setData. Rest funktioniert scheinbar, nur das Editieren nicht.

Falls jemand noch Tipps dazu hat, würde es mich sehr interessieren, wie man das richtig macht. Natürlich sind Links, bzw. Beispiele im Internet auch willkommen. Meine Suche war leider erfolglos.

Mein Problem habe ich auf eine ganz andere Weise gelöst jetzt, aber wie gesagt, die Lösung über die Ableitung interessiert mich auch.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: QSqlTableModel UserRole

Beitrag von Christian81 »

Dann sind die Beispiele und Anleitungen falsch - wenn ich von einer Klasse ableite dann sollte ich auch exakt dessen virtuelle Funktionen aufrufen und nicht einfach die von irgend einer Basisklasse.
Bzgl. dem Model - QSqlQueryModel sind nur einfache (Hilfs)-Models zur schnellen Darstellung von Daten aus der Datenbank. Sobald man etwas sinnvolleres damit machen will (wie z.B. Daten wieder zurück in die DB) sollte man sein eigenes Model benutzen. Siehe z.B. auch hier: http://qtforum.de/forum/viewtopic.php?f ... querymodel
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
miki11
Beiträge: 30
Registriert: 27. Oktober 2008 13:32

Re: QSqlTableModel UserRole

Beitrag von miki11 »

Wie gesagt, QSqlTableModel::setData hatte ich auch versucht, hat auch nicht die Daten verändert. Wenn ich das nicht abgeleitete QSqlTableModel direkt nutze, dann ist alles OK. Spricht, ich vermute, ich müsste setData neu implementieren, damit die Funktion wieder gegeben ist. Jedoch weiß ich nicht, wie das geht, ohne ein eigenes Storage zu implementieren und damit auch data() usw. alles neu implementieren zu müssen.
Denn dass geht, meine Meinung nach an den Sinn von C++ "wiederverwenden" vorbei, wenn ich alles neu schreiben muss.
MichaelS
Beiträge: 240
Registriert: 27. Dezember 2005 12:49

Re: QSqlTableModel UserRole

Beitrag von MichaelS »

miki11 hat geschrieben:Wie gesagt, QSqlTableModel::setData hatte ich auch versucht, hat auch nicht die Daten verändert.
Und was genau hast Du versucht?
miki11
Beiträge: 30
Registriert: 27. Oktober 2008 13:32

Re: QSqlTableModel UserRole

Beitrag von miki11 »

MichaelS hat geschrieben:
miki11 hat geschrieben:Wie gesagt, QSqlTableModel::setData hatte ich auch versucht, hat auch nicht die Daten verändert.
Und was genau hast Du versucht?
Das was Christian81 vorschlägt?! Und du Zitiert hast! QSqlTableModel::setData statt QSqlQueryModel::setData im obigen Kode zu verwenden.

Aber was auch immer ich versucht habe, die Frage ist, wie man QSqlTableModel ableitet und setData(...) { ... } richtig füllt, damit die gleiche Funktion erfüllt ist, wie das bei QSqlTableModel bereits gegeben ist. Um das Original als Ausgangspunkt für Veränderungen zu haben.
veeman
Beiträge: 277
Registriert: 3. Oktober 2012 01:43
Kontaktdaten:

Re: QSqlTableModel UserRole

Beitrag von veeman »

QSqlTableModel wird wohl die UserRole weder setzen noch auslesen, oder einfach gesagt ignorieren.
Da wirst du wohl irgendeine eigene Verknüpfung basteln müssen.

Ansonsten wird sich durch so eine Implementierung die abgeleitete Klasse genauso wie das original verhalten:

Code: Alles auswählen

class MCSqlTableModel : public QSqlTableModel {
    Q_OBJECT

public:
   MCSqlTableModel(QObject* parent = 0, QSqlDatabase db = QSqlDatabase());
      : QSqlTableModel(parent, db)
   {
   }

   virtual Qt::ItemFlags flags(const QModelIndex & index) const
   {
      return QSqlTableModel::flags(index);
   }

   bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::DisplayRole)
   {
      // hier role == UserRole prüfen und intern assoziieren
      return QSqlTableModel::setData(index, value, role);
   }

   // ggf data() implementieren um den Wert von UserRole zurückzugeben
};
Antworten