PDA

View Full Version : How to highlight certain items in QTeeView?



NPS
9th June 2013, 13:43
I have a QTreeView filled with some items and when a specific event occurs I want to highlight a few specific items in that view (by for example changing their color). How do I do that? And please, when you answer, tell the whole story, because I'm new to Qt and still many obvious things are not obvious to me.

A couple of similar threads suggest overloading the model and specifically the "data()" method to return custom color (that's correct, right?) but this would require each item to know if it should be highlighted or not. Can I somehow store that information within each item?

wysota
9th June 2013, 20:03
It really depends what the semantics of your actions are. In general you can implement what you want either in the model, in the view or in the delegate so in any of the three components that make the ItemViews architecture. Implementing this behaviour in the model makes sense if assuming that you have more than one view on the same model, you want the same items highlighted in both views. Then you need to emit dataChanged in the model for the indexes that are to be updated and return the changed value from data(). Another solution is to keep a list of highlighted items in the view or delegate and reimplement proper methods in those components. Sorry for not "telling the whole story" but I'd have to quote half of the documentation so instead of that you can just read it yourself :)

NPS
11th June 2013, 19:38
Ok, you really have to tell me more, because right now I can't move forward. Let's go the first thing you suggested - implement it in the model. I tried this:

class HighlightModelItem : public QStandardItem
{
private:
bool highlighted;

public:
HighlightModelItem(void);
explicit HighlightModelItem(const QString & text);
HighlightModelItem(const QIcon & icon, const QString & text);
explicit HighlightModelItem(int rows, int columns = 1);
virtual ~HighlightModelItem(void);
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
void setHighlighted(bool value);
};

(BTW, I had no idea how subclassing should look like, I can't find EVEN ONE example on the internet... so I just reimplemented ctors/dtor from QStandardItem. :P)


QVariant HighlightModelItem::data(const QModelIndex & index, int role) const
{
if (role == Qt::BackgroundColorRole && highlighted)
{
return QColor(255, 0, 0);
}
return data(index, role);
}

void HighlightModelItem::setHighlighted(bool value)
{
highlighted = value;
emitDataChanged();
}

And I'm just using this instead of QStandardItem in QStandardItemModel object:

QStandardItemModel * blocksModel = new QStandardItemModel();
blocksModel->setHorizontalHeaderItem(0, new HighlightModelItem("Blocks"));
inputCategory = new HighlightModelItem("Input blocks");
processCategory = new HighlightModelItem("Processing blocks");
outputCategory = new HighlightModelItem("Output blocks");
blocksModel->setItem(0, inputCategory);
blocksModel->setItem(1, processCategory);
blocksModel->setItem(2, outputCategory);
treeView->setModel(blocksModel);

But, as you can guess, this doesn't work. "HighlightModelItem::data()" never gets called (despite me calling HighlightModelItem::setHighlighted()" in my code), why is that?

wysota
11th June 2013, 20:10
I'm sorry, that's not even remotely what you need to do.

http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html

Read at least the "Subclassing" part and links leading from it.