2

I want to override the function drawBranches() in QTreeView.
I subclassed the QTreeView class, then I copied drawBranches() function from here. Before change anything in this function, I want to ensure that it works first, but build failed with this error:

error: 'const QTreeViewPrivate* QTreeView::d_func() const' is private
 inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr)); } \

Here is my code:

class MyTreeView : public QTreeView
{
    Q_OBJECT
public:
    MyTreeView(QWidget *parent =0) : QTreeView(parent) {}
    void drawBranches(QPainter * painter, const QRect &rect, const 
                        QModelIndex &index)const
    {
        Q_D(const QTreeView);
        const bool reverse = isRightToLeft();
        const int indent = d->indent;
        const int outer = d->rootDecoration ? 0 : 1;
        const int item = d->current;
        const QTreeViewItem &viewItem = d->viewItems.at(item);
        int level = viewItem.level;
        QRect primitive(reverse ? rect.left() : rect.right() + 1, rect.top(), indent, rect.height());

        ....// Moore lines that I copied

            else
                opt.state &= ~QStyle::State_MouseOver;
            style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt, painter, this);
            current = ancestor;
            ancestor = current.parent();
        }
        painter->setBrushOrigin(oldBO);
}

};

There is many lines where d pointer is used and it is private, e.g d->indent; .

How can I get a reference to this pointer without violating private role?

Why I want to override this function: I want to hide the expand/collapse indicator for all items except those who have level zero (height level) and I guess by overriding this function I can do that.

Thanks

Phiber
  • 942
  • 3
  • 14
  • 36

1 Answers1

1

You'll need to consult the reference on using Qt PIMPL idiom.

Every d_func is private. You need to declare your own. Yours is a special case because you don't derive from QTreeViewPrivate, thus the type returned is still QTreeViewPrivate*. Qt provides a handy macro that does the work for you:

// Interface
#include <QTreeView>

class MyTreeView : public QTreeView
{
  Q_OBJECT
  Q_DECLARE_PRIVATE(QTreeView)
public:
  MyTreeView(QWidget * parent = {}) : QTreeView{parent} {}
protected:
  void drawBranches(QPainter *, const QRect &, const QModelIndex&) const override;
};
// Implementation
#include <private/qtreeview_p.h>

void MyTreeView::drawBranches(QPainter * painter, const QRect &rect, const 
                              QModelIndex &index)const
{
  Q_D(const QTreeView);
  ...
}

Also, instead of copying code from a random repository, you should copy it from the official mirror.

Kuba hasn't forgotten Monica
  • 88,505
  • 13
  • 129
  • 275
  • Thanks for response and thanks for the hint: '' from the official mirror ". I have an issue with QT += gui-private that refuse to include but I guess I can resolve it. – Phiber May 25 '17 at 15:12
  • add QT += widgets-private instead of gui-private get it works – Phiber May 25 '17 at 15:57