Adding a right-click menu for specific items in QTreeView
Asked Answered
C

1

43

I'm writing a Qt desktop application in c++ with Qt Creator.

I declared in my main window a treeView, and a compatible model.

Now, I would like to have a right-click menu for the tree item. Not for all of the items, but for a part of them, for example: for the tree elements with an even index.

I tried adding a simple context menu with the following code:

in the .h file:

QStandardItemModel* model;
QMenu* contextMenu;
QAction* uninstallAction;
private slots:
    void uninstallAppletClickedSlot();

and in the .cpp file:

in the constructor:

ui->treeView->setModel(model);
contextMenu = new QMenu(ui->treeView);
ui->treeView->setContextMenuPolicy(Qt::ActionsContextMenu);
uninstallAction = new QAction("Uninstall TA",contextMenu);
ui->treeView->addAction(uninstallAction);
connect(uninstallAction, SIGNAL(triggered()), this, SLOT(uninstallAppletClickedSlot()));

and a slot:

void MainWindow::uninstallAppletClickedSlot()
{

}

this code gives me a context menu with the wanted action, but do you have any idea how can I add this action only for the QStandardItems with the even indexes??

BTW, I'm adding items to the treeView by the following way:

void MainWindow::AddItem(QString name)
{
QStandardItem *parentItem = model->invisibleRootItem();
QStandardItem *app = new QStandardItem(name);
parentItem->appendRow(app);
}

I googled a lot, but found nothing :(

thanks in advance!

Carswell answered 5/3, 2014 at 12:56 Comment(0)
V
65

I would do this in the following way:

Configure the context menu

ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->treeView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onCustomContextMenu(const QPoint &)));

Implement the context menu handling

void MainWindow::onCustomContextMenu(const QPoint &point)
{
    QModelIndex index = ui->treeView->indexAt(point);
    if (index.isValid() && index.row() % 2 == 0) {
        contextMenu->exec(ui->treeView->viewport()->mapToGlobal(point));
    }    
}
Vulgarian answered 5/3, 2014 at 13:7 Comment(4)
thanks, @vahancho, I followed your instructions, but the result is: once I press on a row with an even index - I can see a little point appears in the form, and once I press on a row with odd index - nothing appears. this is good, but the menu doesn't appear at all! i.e, the exec() function doesn't do the wanted action. Do you have any more idea? thanks a lot!Carswell
@user1835297, actually you have to construct your menu beforehand. I did not include that code in my answer. You simply need to: contextMenu->addAction("Uninstall TA", this, SLOT(uninstallAppletClickedSlot()); or so.Vulgarian
Use ui->treeview->viewport()->mapToGlobal(point) instead, if you experience a strange offset of the menu.Krone
That's because item views are QAbstractScrollareas. Thus "The exception to this rule is QAbstractScrollArea and its subclasses that map the context menu event to coordinates of the viewport()." from the docs applies.Sickening

© 2022 - 2024 — McMap. All rights reserved.