[Solved] Reimplementing QStyledItemDelegate::paint in a subclass wipes out all custom style on the corresponding view, including the Windows 7 style



  • Our application uses Qt's model/view architecture and I've inherited the task of finding out why our QTreeView subclass has recently lost all of it's style. Not only has it lost all the stylesheets we've set on it ourselves, but it's lost the Aero-themed style that being compiled and run on Windows 7 had applied. See these two screenshots for examples of what I'm talking about.

    !http://i.stack.imgur.com/zBjkE.png(Screenshot)!

    On the left is the undesirable style that we have now and on the right is what we want and what we have before. I know that the shade of blue on the left is the default selection colour for the QTreeView so I am assuming that something is overriding all custom style settings.

    We have a class called EntityDelegate which is a subclass of QStyledItemDelegate. We are setting an instance of this class as the delegate of our view.

    I've narrowed the problem down to the following function in EntityDelegate. When I comment out this function, the problem goes away.

    @void EntityDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
    {
    QStyleOptionViewItemV4 editedOpt = option;
    editedOpt.decorationSize.rwidth() *= 3;
    QModelIndex proxyIndex = parentBrowser_.proxyModel.mapToSource(index);
    QStyledItemDelegate::paint(painter, editedOpt, proxyIndex);
    }@

    My problem is that this function is needed by another team so I can't get rid of it and have to work around the issue. I only have a basic understanding of both Qt's model/view architecture and stylesheets. When reading the docs for QStyledItemDelegate::paint I came across the following passage

    bq. When reimplementing paint in a subclass. Use the initStyleOption() to set up the option in the same way as the QStyledItemDelegate; the option will always be an instance of QStyleOptionViewItemV4. Please see its class description for information on its contents.

    I'm pretty sure this is the path I need to follow but I don't know what to make of this. I read the docs for QStyledItemDelegate::initStyleOption but I'm not sure how it can help me here.

    My question: What do I need to do to EntityDelegate::paint to both preserve the effect it's contents has on the model while restoring our original style settings?



  • I've figured out what it was. The author of EntityDelegate::paint had missed a line. the function should read

    @void EntityDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
    {
    QStyleOptionViewItemV4 editedOpt = option;
    editedOpt.decorationSize.rwidth() *= 3;
    QModelIndex proxyIndex = parentBrowser_.proxyModel.mapToSource(index);
    initStyleOption( &editedOpt, index );
    QStyledItemDelegate::paint(painter, editedOpt, proxyIndex);
    }@

    The second last line was missing which is necessary when reimplementing QStyledItemDelegate::paint. When calling the base class at the end of the function, the index is painted using only the options specified in editedOpt. In this case that meant only the alteration of decorationsize().rwidth() and all other details that came in with option, including style, were lost.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.