Search code examples
pythonqtpyqtqtreewidget

Invoking context menu in QTreeWidget


I would like to popup a menu, when user clicks on an object in QTreeWidgetItem. I though about catching signal contextMenuRequested from QWidget and then retrieving index from the view using itemAt. But this doesn't seem very pretty. Is there any easier way to be able to call a menu on an item inside a view?


Solution

  • Write your own custom ItemDelegate and handle the click event in QAbstractItemDelegate::editorEvent. You can retreive the data in the cell from the QModelIndex. In C++ it would look like this:

    class ItemDelegate: public QItemDelegate
    {
    public:
        ItemDelegate(ContextMenuHandler *const contextMenu, QObject *const parent )
            : QItemDelegate(parent)
            , m_contexMenu(contextMenu) 
        {
        }
    
        bool editorEvent( 
                QEvent * event, 
                QAbstractItemModel * model, 
                const QStyleOptionViewItem & option, 
                const QModelIndex & index )
        {
            if((event->type()==QEvent::MouseButtonPress) && index.isValid())
            {
                QMouseEvent *const mouseEvent = qobject_cast<QMouseEvent>(event);
                if(mouseEvent && (mouseEvent->button()==Qt::RightButton))
                {
                    return m_contexMenu->showContextMenu(mouseEvent->pos(), index);
                }
            }
        }
        ContextMenuHandler *const m_contextMenu;
    };
    
    treeWidget->setItemDelegate(new ItemDelegate(contextMenuHandler,treeWidget));