0
votes

I have a subclass of QTreeView. I need a custom context menu for specific items in it. To get this I set the context menu policy and connect the signal "customContextMenuRequested" in the constructor of the subclass of QTreeView:

setContextMenuPolicy( Qt::CustomContextMenu );

QObject::connect( this, SIGNAL( customContextMenuRequested( const QPoint & ) ), this, SLOT( onCustomContextMenu( const QPoint & ) ) );

Now, in the slot function "onCustomContextMenu" I get the position for the context menu creation as a QPoint. I would like to get the QStandardItem that is shown on this position. I tried this:

void t_my_tree_view::onCustomContextMenu( const QPoint &point )
{
  QModelIndex index = this->indexAt( point );
  QStandardItem* item_ptr = m_item_model->item( index.row, index.column() );
}

m_item_model is a pointer to the QStandardItemModel that is the model in this subclass of the QTreeview.

The problem is, that the "item_ptr" that I get is wrong sometimes, or it is NULL. It will be NULL if my model looks like this:

invisibleRootItem
|-item_on_level_1
|-item_on_level_2
|-item_on_level_2
|-item_on_level_2 <-- this is the item where the right click was
|-item_on_level_2

What am I doing wrong? How can I get the item that i rightclick?

2

2 Answers

2
votes

if your contextMenuRequest selects the TreeItem then you could use QTreeView::currentIndex() to get the actual selected QModelIndex.

Use QStandardItemModel::itemFromIndex(const QModelIndex&) to get the pointer to the QStandardItem.

Just in case, check if the ptr is null and you should be good to go

1
votes

You should map QPoint coordinates to view->viewport() coordinates.

Prefferable way is to implement custom QStyledItemDelegate with overriding editorEvent, like:

bool LogDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, QStyleOptionViewItem const& option, QModelIndex const& index)
{
    switch (event->type())
    {
    case QEvent::MouseButtonRelease:
        {
            QMouseEvent* me = static_cast<QMouseEvent *>(event);
            if (me->button() == Qt::RightButton)
            {
                QMenu menu;
                QAction* copy = new QAction("Copy", this);
                connect(copy, SIGNAL( triggered() ), SIGNAL(copyRequest()));
                menu.addAction(copy);
                menu.exec(QCursor::pos());
                copy->deleteLater();
            }
        }
        break;

    default:
        break;
    }

    return QStyledItemDelegate::editorEvent(event, model, option, index);
}