QTableView: farbige Zelle

Alles rund um die Programmierung mit Qt
tux.2000
Beiträge: 13
Registriert: 19. Juni 2008 08:09

QTableView: farbige Zelle

Beitrag von tux.2000 »

Hallo Gemeinde.

Ich benutze das QTableView-Widget in Verbindung mit einem QAbstractTableModel zur Anzeige/Verwaltung von einigen Daten.

Die Tabelle wird zur Laufzeit relativ groß. Der Übersichtlichkeit wegen würde ich gerne etwas Farbe ins Spiel bringen. Es würde bereits helfen, wenn Zellen einer einzigen Spalte (von insg. 5) ausgewertet und je nach Inhalt farbig hinterlegt werden.

Also z.B. alle Zellen der Spalte 4:
Wenn (Wert der Zelle == 1) dann Hintergrundfarbe Orange, sonst Grün.

Ist der Aufwand sehr groß, um dies zu erreichen?
Wünschenswert wäre direkter Beispielcode für das oben beschriebene Model/View-Konzept (MVC).

Vielen Dank für eure Aufmerksamkeit und evtl. Hilfe bei meinem "visuellen Luxusproblemchen".
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Im Model bei ::data() für die Background role eine geeignete Farbe zurückgeben sollte gehen.
http://doc.trolltech.com/4.7/qabstracti ... .html#data
http://doc.trolltech.com/4.7/qt.html#ItemDataRole-enum
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Das wird alles (Farben, Alignments, Fonts, usw.) via data()-Methode (die du ja bereits hast) abgefragt:
http://doc.qt.nokia.com/4.7/qabstractit ... .html#data

Siehe dazu die anderen "Roles" (du wirst ja erst "DisplayRole" haben):
http://doc.qt.nokia.com/4.7/qt.html#ItemDataRole-enum

hth..

[EDIT] zu spät :wink:
dazligth
Beiträge: 6
Registriert: 27. Oktober 2013 16:57

Re: QTableView: farbige Zelle

Beitrag von dazligth »

Hallo Community,

mein Einstandspost :)

Ich schlage mich mit genau dem selben Problem rum und komme nicht weiter.
Verstehe ich es richtig, dass die Ansichtseinstellungen für die View im Model mit gespeichert sind?

Wenn dem so ist, warum bekomme ich dann für die Text-Farbe im unten aufgezeigten Beispiel ein "QVariant(Invalid)" zurück.
Und klar, vermutlich klappt deswegen auch das .setValue(QColor(Qt::red)) im folgenden nicht. Wo liegt mein Fehler?

Code: Alles auswählen

                
qDebug () << myModel->data(myModel->index((myModel->rowCount()-1)),Qt::ForegroundRole); // Rückgabe: QVariant(Invalid)
myModel->data(myModel->index((myModel->rowCount()-1)),Qt::ForegroundRole).setValue(QColor(Qt::red));

qDebug () << myModel->index((myModel->rowCount()-1)).data(Qt::ForegroundRole); // Rückgabe: QVariant(Invalid)
myModel->index((myModel->rowCount()-1)).data(Qt::ForegroundRole).setValue(QColor(Qt::red));
archer
Beiträge: 306
Registriert: 2. Februar 2006 09:56

Re: QTableView: farbige Zelle

Beitrag von archer »

Was willst du mit der Zeile bezwecken:

Code: Alles auswählen

myModel->data(myModel->index((myModel->rowCount()-1)),Qt::ForegroundRole).setValue(QColor(Qt::red));
Wenn du eine Farbe in das Modell setzen willst mußt du myModel->setData(...) aufrufen.
dazligth
Beiträge: 6
Registriert: 27. Oktober 2013 16:57

Re: QTableView: farbige Zelle

Beitrag von dazligth »

Genau, ich will im meiner ListView, hinter dem ein Model hängt, bei bestimmten Ereignissen die Textfarbe für eine Zeile ändern.

Jetzt wollte ich versuchen zu schauen was denn die aktuelle Farbe für das letzte Element ist:

Code: Alles auswählen

qDebug() << myModel->data(myModel->index((myModel->rowCount()-1)),Qt::ForegroundRole);
Rückgabe ist QVariant(Invalid) was mich schon wundert.

Gut dann der Versuch mit setData in dieser Form:

Code: Alles auswählen

myModel->setData(myModel->index((myModel->rowCount()-1)),QVariant(QColor(Qt::red)),Qt::ForegroundRole);
Was auch nicht klappt. Kompliert zwar, aber es gibt keine Änderung.
Zuletzt geändert von dazligth am 18. Januar 2014 02:29, insgesamt 1-mal geändert.
dazligth
Beiträge: 6
Registriert: 27. Oktober 2013 16:57

Re: QTableView: farbige Zelle

Beitrag von dazligth »

Ich benutze eine List View und ein QStringListModel? Liegt es vielleicht am Model?

Oder muss ich nach dem verändern von "SetData" ein emit myModel->dataChanged() absetzen? Das macht der doch automatisch, soweit ich mich eingelesen habe.
sigvdr
Beiträge: 100
Registriert: 1. Juli 2008 19:29

Re: QTableView: farbige Zelle

Beitrag von sigvdr »

Erstelle dein eigenes Model abgeleitet von QAbstractListModel
Als absolutes Minimum sind im für ein "Readonly" Model die virtuellen Methoden "rowCount(...)" und "data(...)" zu erstellen.
In deiner dann erstellten Methode "data(...)" kannst du dann die Farben setzen.

Code: Alles auswählen

class StringListModel : public QAbstractListModel
{
    Q_OBJECT
public:
    explicit StringListModel(QObject *parent = 0);
    int rowCount(const QModelIndex & parent = QModelIndex()) const;
    QVariant data(const QModelIndex &index, int role) const;
private:
    QStringList stringList;
};

Code: Alles auswählen

int StringListModel::rowCount(const QModelIndex & /*parent*/) const {
    return stringList.count();
}
QVariant StringListModel::data(const QModelIndex &index, int role) const {
    if ( role == Qt::DisplayRole) {
        if ( index.row() < stringList.count() ) {
            return stringList[index.row()];
        }
    } else if ( role == Qt::BackgroundRole) {
           if (stringList[index.row()] == "?????????") {
                return QBrush(Qt::cyan);
           }
    }
    return QVariant();
}
Zuletzt geändert von sigvdr am 20. Januar 2014 08:11, insgesamt 1-mal geändert.
dazligth
Beiträge: 6
Registriert: 27. Oktober 2013 16:57

Re: QTableView: farbige Zelle

Beitrag von dazligth »

Ok danke, dass muss ich mir mal genauer anschauen. Ist Neuland für mich.
Darf ich daraus deuten, dass es mit dem bisherigen Model nicht gehen kann?

Und wenn ja, was ist der Grund dafür?
Gibt es die Roles dort nicht, sind die protected oder noch was ganz anderes?
sigvdr
Beiträge: 100
Registriert: 1. Juli 2008 19:29

Re: QTableView: farbige Zelle

Beitrag von sigvdr »

Was im einzelnen noch mit QStringListModel machbar ist oder nicht kann ich dir auch nicht sagen.

Code: Alles auswählen

myModel->setData(myModel->index((myModel->rowCount()-1)),QVariant(QColor(Qt::red)),Qt::ForegroundRole);
Hier versuchst du eine Farbe "QColor" zu setzen, Qt:ForegroundRole erwartet aber "QBrush"!

Aber!
Es lohnt sich das Model selbst abzuleiten, das sieht im ersten Moment etwas komplizierter aus macht aber später die Arbeit einfacher.

Ein Beispiel wäre:
Eine Liste mit Zahlen, die negative Werte in rot anzeigt.
Mit deinem Beispiel myModel->setData(...) kannst du die Farbe einer einzelnen Zeile setzen. Dann muss aber auch immer überwacht werden, ob sich die Bedingung (positive oder negative Zahl) für jede die Zeile geändert hat. Ein erhöhter Verwaltungsaufwand für das Basisprogramm das dieses Model nutzt.
Beim abgeleiteten Model aus dem Beispiel wird mit diesem Code alle erledigt.

Code: Alles auswählen

    } else if ( role == Qt::ForegroundRole) {
           if (stringList[index.row()].left(1) == "-") {
                return QBrush(Qt::red);
           }
Gruß Sig
dazligth
Beiträge: 6
Registriert: 27. Oktober 2013 16:57

Re: QTableView: farbige Zelle

Beitrag von dazligth »

Jo cool, danke! Habe ich vestanden, werd ich gleich mal was rumprobieren!
:)
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: QTableView: farbige Zelle

Beitrag von RHBaum »

Dann muss aber auch immer überwacht werden, ob sich die Bedingung (positive oder negative Zahl) für jede die Zeile geändert hat
Das nimmt Dir aber bei der Eigenimplementierung auch keiner ab :-)
Wenn du die Änderung im View sehen willst, musst/solltest du das datachanged aufrufen, sonst zeigt das View an worauf es Lust hat ^^
Aber dabei wird weniger "bewegt" als wenn du das StringlistModel editierst !!!

generell kannst Du mit eigenen Implementierungen von QAbstractItemModel sehr flexible und effizientere Models schreiben, weil du direkt auf die Daten schauen kannst und weniger kopieren musst ... und wenn Du Daten genereierst, dann nur die, die das View auch grad will ... was nicht angezeigt wird, wird auch nicht abgerufen.

Mal ne ganz andere Frage ...
explicit StringListModel(QObject *parent = 0);
Das hab ich noch nie so gesehen :-)
Warum machst den Ctor expliziet ?
hasst du speziellere Ctors mit spezielleren Q Klassen ?

Ciao ...
sigvdr
Beiträge: 100
Registriert: 1. Juli 2008 19:29

Re: QTableView: farbige Zelle

Beitrag von sigvdr »

Dann muss aber auch immer überwacht werden, ob sich die Bedingung (positive oder negative Zahl) für jede die Zeile geändert hat
Das nimmt Dir aber bei der Eigenimplementierung auch keiner ab :-)
Es macht doch aber einen Unterschied ob das zentral (also im Model) oder dezentral im benutzenden Programm und dort Moglicherweise an mehreren Stellen überwacht werden muss.
Mal ne ganz andere Frage ...
explicit StringListModel(QObject *parent = 0);

Das hab ich noch nie so gesehen :-)
Das liegt daran:
dass ich QTCreator benutze
dass ich schreibfaul bin
und deshalb meine Klassen vom QTCreator anlegen lasse.
Und der QTCreator generiert dabei diesen Code. Kennst du einen Grund das nicht so zu machen?

Gruß Sig
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: QTableView: farbige Zelle

Beitrag von RHBaum »

Und der QTCreator generiert dabei diesen Code. Kennst du einen Grund das nicht so zu machen?
DIe frage ist, warum will man verhindern das eine impliziete Typumwandung von QObject * nacht QMeineClasse stattfindet.
in der QObjectHirarchie wirst das ding immer dynamisch anlegen
oder expliet
Also es ist sicher nicht schädlich, aber ob es sinn macht ...

Komisch ist das es der Qt Creator macht,
Das Visual Studio Plugin von Qt (zumindest version 4.x) aber nicht ...

Ciao ...
sigvdr
Beiträge: 100
Registriert: 1. Juli 2008 19:29

Re: QTableView: farbige Zelle

Beitrag von sigvdr »

Die Diskussion über "explicit" sollten wir hier beenden und lieber separat fortführen.
Ich hab dafür mal ein neues Thema aufgemacht
http://www.qtforum.de/forum/viewtopic.php?f=14&t=16192

Gruß Sig
Antworten