Seite 1 von 2

QTableView: farbige Zelle

Verfasst: 8. Januar 2011 11:10
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".

Verfasst: 8. Januar 2011 11:22
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

Verfasst: 8. Januar 2011 11:24
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:

Re: QTableView: farbige Zelle

Verfasst: 16. Januar 2014 00:12
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));

Re: QTableView: farbige Zelle

Verfasst: 16. Januar 2014 07:51
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.

Re: QTableView: farbige Zelle

Verfasst: 18. Januar 2014 00:58
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.

Re: QTableView: farbige Zelle

Verfasst: 18. Januar 2014 01:19
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.

Re: QTableView: farbige Zelle

Verfasst: 19. Januar 2014 19:21
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();
}

Re: QTableView: farbige Zelle

Verfasst: 19. Januar 2014 22:08
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?

Re: QTableView: farbige Zelle

Verfasst: 20. Januar 2014 08:35
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

Re: QTableView: farbige Zelle

Verfasst: 21. Januar 2014 21:44
von dazligth
Jo cool, danke! Habe ich vestanden, werd ich gleich mal was rumprobieren!
:)

Re: QTableView: farbige Zelle

Verfasst: 22. Januar 2014 10:25
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 ...

Re: QTableView: farbige Zelle

Verfasst: 22. Januar 2014 10:46
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

Re: QTableView: farbige Zelle

Verfasst: 22. Januar 2014 12:27
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 ...

Re: QTableView: farbige Zelle

Verfasst: 22. Januar 2014 13:35
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