I have implemented my own delegate for a qTreeWidget, it works perfectly (for what I am using it for at least the widget contains about 30 items and the template affects only top level items) however I think the solution is a bit ugly and I would appreciate some advice.
The technique I use is to create a template widget (which I have created in the designer), assign the data to it, then render it to a pixmap and paint the pixmap.
The ugly part is how I am setting the style on the template widget, ideally I would simply like to apply the appropriate "QTreeView::item" style from my .qss file but aside from string parsing them out of the .qss file manually I don't know how to do that, and all my attempts to use the qstyleoptionview object failed.
{
public:
void setDescription(const QString& s);
private:
Ui::ItemTemplateWidget ui;
};
class ItemTemplate: public QWidget
{
public:
ItemTemplate(QWidget* parent = 0);
void setDescription(const QString& s);
private:
Ui::ItemTemplateWidget ui;
};
To copy to clipboard, switch view to plain text mode
class CustomItemDelegate : public QStyledItemDelegate
{
public:
...
private:
ItemTemplate* mTemplateWidget;
};
class CustomItemDelegate : public QStyledItemDelegate
{
public:
...
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
private:
ItemTemplate* mTemplateWidget;
};
To copy to clipboard, switch view to plain text mode
{
QString s
= index.
data(ROLE_DESCRIPTION
).
toString();
if (!s.isEmpty() && !s.isNull())
{
painter->save();
QStyleOptionViewItemV4 opt = option;
initStyleOption(&opt, index);
if (option.
state & QStyle::State_Enabled) {
mTemplateWidget->setStyleSheet("somecustomstyle");
if (option.
state & QStyle::State_Selected) {
mTemplateWidget->setStyleSheet("somecustomstyle");
}
else if (option.
state & QStyle::State_MouseOver) {
mTemplateWidget->setStyleSheet("somecustomstyle");
}
}
else
{
mTemplateWidget->setStyleSheet("somecustomstyle");
}
mTemplateWidget->setDescription(s);
mTemplateWidget->setGeometry(0, 0, option.rect.width(), option.rect.height());
painter->drawPixmap(option.rect, pix);
painter->restore();
}
else
{
QStyledItemDelegate::paint(painter, option, index);
}
void CustomItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QString s = index.data(ROLE_DESCRIPTION).toString();
if (!s.isEmpty() && !s.isNull())
{
painter->save();
QStyleOptionViewItemV4 opt = option;
initStyleOption(&opt, index);
if (option.state & QStyle::State_Enabled)
{
mTemplateWidget->setStyleSheet("somecustomstyle");
if (option.state & QStyle::State_Selected)
{
mTemplateWidget->setStyleSheet("somecustomstyle");
}
else if (option.state & QStyle::State_MouseOver)
{
mTemplateWidget->setStyleSheet("somecustomstyle");
}
}
else
{
mTemplateWidget->setStyleSheet("somecustomstyle");
}
mTemplateWidget->setDescription(s);
mTemplateWidget->setGeometry(0, 0, option.rect.width(), option.rect.height());
QPixmap pix = QPixmap::grabWidget(mTemplateWidget);
painter->drawPixmap(option.rect, pix);
painter->restore();
}
else
{
QStyledItemDelegate::paint(painter, option, index);
}
To copy to clipboard, switch view to plain text mode
Thanks in advance!
Bookmarks