Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I not see the drop indicator in a QTableView?

I use drag and drop in my QTableView (works). However, I do not see any drop indicator. I should see a line where the drop is supposed to be inserted, shouldn't I? At least here they say so.

My init is pretty much standard.

    // see model for implementing logic of drag
    this->viewport()->setAcceptDrops(allowDrop);
    this->setDragEnabled(allowDrag);
    this->setDropIndicatorShown(true);
    this->m_model->allowDrop(allowDrop);

I have no idea why I do not see the indicator. A style sheet is used with the views, could that be the reason. However, I have disabled the stylesheet and still do not see it.

The view uses entire rows for selection, not sure if this causes an issue. So any hint is appreciated.

-- Edit --

As of the comment below, tried all selection modes: single, multi or extended, no visual effect. Also tried cell instead of row selection, again no improvement.

-- Edit 2 --

Currently evaluating another style proxy example, similar to the one below, originally referenced here

-- Related --

QTreeView draw drop indicator
How to highlight the entire row on mouse hover in QTableWidget: Qt5
https://forum.qt.io/topic/12794/mousehover-entire-row-selection-in-qtableview/7
https://stackoverflow.com/a/23111484/356726

like image 512
Horst Walter Avatar asked Jun 13 '16 17:06

Horst Walter


1 Answers

I faced the same problem, I tried two options which both worked for me. IIRC, the help came from an answer on SO.

  • if you are subclassing QTreeView, you can override its paintEvent() method. It is calling by default the drawTree() method and the paintDropIndicator() one (the latter being part of QAbstractItemView private class).

You can call drawTree() from your paintEvent(), and it should override the default drag and drop indicator as well :

class MyTreeView : public QTreeView
{
public:
    explicit MyTreeView(QWidget* parent = 0) : QTreeView(parent) {}

    void paintEvent(QPaintEvent * event)
    {
        QPainter painter(viewport());
        drawTree(&painter, event->region());
    }
};
  • the other method is to subclass QProxyStyle and overriding the drawPrimitive() method. When you get the element QStyle::PE_IndicatorItemViewItemDrop as a parameter, you can paint it your own way.

The code will look like this:

class MyOwnStyle : public QProxyStyle
{
public:
    MyOwnStyle(QStyle* style = 0) : QProxyStyle(style) {}

    void drawPrimitive(PrimitiveElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const
    {
        if (element == QStyle::PE_IndicatorItemViewItemDrop)
        {
            //custom paint here, you can do nothing as well
            QColor c(Qt::white);
            QPen pen(c);
            pen.setWidth(1);

            painter->setPen(pen);
            if (!option->rect.isNull())
                painter->drawLine(option->rect.topLeft(), option->rect.topRight());
        }
        else
        {
            // the default style is applied
            QProxyStyle::drawPrimitive(element, option, painter, widget);
        }
    }
};
like image 127
IAmInPLS Avatar answered Nov 08 '22 03:11

IAmInPLS