2

I have a class (EditorTagManager) that contains a QTreeWidget. During runtime, the tree can contain any number of tag items, all of which are checkable. I'm trying to add horizontal lines between the QTreeWidgetItems in order to make it clear that these tags are unrelated and are meant to be separate from one another (each item is a root-level node).

From my research on the subject, I've figured out the only way to control the appearance of QtreeWidgetItems to any meaningful extent is to subclass QStyledItemDelegate and bind the delegate to the QTreeWidget. It's kind of an abstract concept so I don't fully understand it. Since I’ve never had to subclass a Qt object before, I'm not sure if I’m doing it correctly.

Since the Qt Documentation didn't really explain how to do this, I used the settingsdialog.cpp/.h files from the Clementine 1.0.1 source code as my guide/reference because Clementine's preferences window uses similar separators on its QTreeWidget. I'm trying to reverse-engineer my own solution from Clementine's code, the only problem is Clementine's implementation of this does things I don't need (so I have to figure out what's relevant to my code and what's not). That's what got me up to this point; my code is very similar to the Clementine code (I just changed the delegate class name):

Here is my current delegate header declaration in editortreemanager.h:

class TagListDelegate : public QWidget
{

public:
    TagListDelegate(QObject* parent);
    void paint(QPainter* painter, const QStyleOptionViewItem& option,
                const QModelIndex& index) const;
};

Here is my current delegate source in editortreemanager.cpp:

TagListDelegate::TagListDelegate(QObject *parent) :
    TagListDelegate(parent){

}

void TagListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                            const QModelIndex &index) const{

}

Even though TagListDelegate::paint() doesn't actually do anything yet, I just want to get this code working correctly before I try to change the appearance of the QTreeWidgetItems. My goal is to keep this as simple as possible for now.

Everything compiled fine until I told the QTreeWidget (ui->AvailableTags) to use the delegate:

ui->AvailableTags->setItemDelegate(new TagListDelegate(this)); 

The compiler error reads:

/home/will/qt_projects/robojournal/ui/editortagmanager.cpp:211: error: no matching function for call to 'QTreeWidget::setItemDelegate(TagListDelegate*)'

I’m in a bit over my head here so I would definitely appreciate some help in figuring this out.

UPDATE (7/30/13):

My Delegate class now looks like this:

Source:

TagListDelegate::TagListDelegate(QStyledItemDelegate *parent) :
    TagListDelegate(parent){

}

void TagListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                            const QModelIndex &index) const{

    QStyledItemDelegate::paint(painter, option, index);

}

Header declaration:

class TagListDelegate : public QStyledItemDelegate
{

public:
    TagListDelegate(QStyledItemDelegate* parent);
    void paint(QPainter* painter, const QStyleOptionViewItem& option,
                const QModelIndex& index) const;
};

UPDATE (7/31/13)

Here is what my classes look like now:

header:

class TagListDelegate : public QStyledItemDelegate
{

public:
    TagListDelegate(QObject* parent);
    QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
    void paint(QPainter* painter, const QStyleOptionViewItem& option,
                const QModelIndex& index) const;
};

source:

TagListDelegate::TagListDelegate(QObject *parent)
    : TagListDelegate(parent){

}

QSize TagListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
     QSize ret = QStyledItemDelegate::sizeHint(option, index);
     return ret;
}


void TagListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                            const QModelIndex &index) const{

    QStyledItemDelegate::paint(painter, option, index);

}
Will Kraft
  • 553
  • 1
  • 8
  • 23

1 Answers1

2

You're not subclassing QStyledItemDelegate in your code. You're subclassing QWidget. Change

class TagListDelegate : public QWidget

to:

class TagListDelegate : public QStyledItemDelegate

And don't forget to include the header:

#include <QStyledItemDelegate>
IAmInPLS
  • 4,051
  • 4
  • 24
  • 57
thuga
  • 12,601
  • 42
  • 52
  • Ok, I've done that but invoking the delegate by running ui->AvailableTags->setItemDelegate(new TagListDelegate(this)); still doesn't work. – Will Kraft Jul 30 '13 at 16:42
  • @WillKraft In your constructor you're asking for a `QStyledItemDelegate` type object as a parent, when you should be asking for a `QWidget` or a `QObject` type. – thuga Jul 31 '13 at 06:25
  • Thuga: Your latest advice helped a little bit; the code compiles now when I invoke the delegate but the app segfaults whenever the Delegate is instantiated. The debugger says it has something to do with the constructor, specifically that the parent (this) is not available. My latest code (see above) is basically a stripped-down version of the delegate code from Clementine so I’m not sure what the problem is. – Will Kraft Jul 31 '13 at 22:42
  • Actually, I might have just fixed it. It doesn't crash now that I've set the constructor to TagListDelegate::TagListDelegate(QObject *parent) : QStyledItemDelegate(parent){ } – Will Kraft Jul 31 '13 at 22:52
  • Yes, it's definitely fixed now. Thanks for the help. – Will Kraft Jul 31 '13 at 22:53
  • @WillKraft Oh yes, you do want to call the superclass' constructor in your subclass' constructor initialization list and not the same class' constructor. Sorry I missed that. I'm glad you managed to solve it. – thuga Aug 01 '13 at 06:08