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

1

7

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://mcmap.net/q/1626932/-qtableview-how-to-hover-an-entire-row-on-mouse-over

Irisation answered 13/6, 2016 at 17:13 Comment(2)
Unclear of the context but: it has to do with selection mode as well. What is the setting? E.g. tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);Adenoma
tried all 3 modes: single, multi, extended - no effectIrisation
B
3

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);
        }
    }
};
Bacitracin answered 14/6, 2016 at 8:6 Comment(2)
Tried it, I have used the QProxyStyleApproach . I see the draw line part being called, but see no visual impact in my very case. Just looks like before. Will try some of the other virtual implementations doc.qt.io/qt-5/qproxystyle.html#QProxyStyle The rect passed seems to always have 0x0 size.Irisation
Here forum.qt.io/topic/62496/… they discuss the same approach (QProxyStyle), but it seems NOT to to be applicable for QTableViewIrisation

© 2022 - 2024 — McMap. All rights reserved.