Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QTableView context menu get QModelIndex information



  • I have a context menu like this:

    mTableContextMenu = new QMenu(this);
    mTableContextMenu->addAction(QIcon(":/copy.png"), "Copy Url to Clipboard");
    

    and connected like this:
    connect(ui->tableView, &QTableView::customContextMenuRequested, this, &MainWindow::customContextMenuRequested);

    Inside the customContextMenuRequested:

    auto index = ui->resultsTableView->indexAt(pos);
    
    if (index.isValid()) {
        auto point = ui->tableView->viewport()->mapToGlobal(pos);
        mTableContextMenu->popup(point);
    }
    

    Now I was wondering, how can I get the QModelIndex information for the url in order to make the action to work?


  • Qt Champions 2019

    How about looking at the documentation: http://doc.qt.io/qt-5/qtableview.html#indexAt ?



  • @Christian-Ehrlicher

    Now I was wondering, how can I get the QModelIndex information for the url in order to make the action to work?

    I know that indexAt will give me the QModelIndex but as I said, I need to make the action to work with the current right clicked item, like if I press copy url to clipboard I need the QModelIndex in order to get the value but I don't have that in the slot that I connected to the action triggered signal.


  • Qt Champions 2019

    You have the index where the click occurred - what's the problem remembering this until the action gets executed??



  • How am I going to remember? The action and the connection of the triggered signal is not in the same method.
    The context menu is shown in one slot, but it's created in another method with the actions.



  • @Mr-Gisa
    I don't claim to know/understand just what you're doing here, but in some shape or form you save the desired information in, say, a member variable and access that from the other function. If you're saying your mTableContextMenu->popup(point) needs to know about the index, instead of directly creating a base QMenu you could derive from that to add a member to hold the extra information, and set that from your customContextMenuRequested() before calling popup().



  • void MainWindow::customContextMenuRequested(const QPoint &pos){
    const QModelIndex index = ui->resultsTableView->indexAt(pos);
    if (index.isValid()) {
    const QPoint point = ui->tableView->viewport()->mapToGlobal(pos);
    QMenu* tableContextMenu = new QMenu(this);
    connect(tableContextMenu,&QMenu::aboutToHide,tableContextMenu,&QMenu::deleteLater);
    QAction* copyUrlAction = new QAction(QIcon::fromTheme(QStringLiteral("edit-copy"),QIcon(QStringLiteral(":/copy.png")), tr("Copy Url to Clipboard"),tableContextMenu);
    const QString urlString = index.data().toString();
    connect(copyUrlAction,&QAction::triggered,this,[urlString]()->void{
    QMimeData* mimeDt = new QMimeData;
    mimeDt->setUrls({QUrl::fromUserInput(urlString)});
    QGuiApplication::clipboard()->setMimeData(mimeDt);
    });
    tableContextMenu->addAction(copyUrlAction);
    tableContextMenu->popup(point);
    }
    }
    


  • @Mr-Gisa said in QTableView context menu get QModelIndex information:

    How am I going to remember? The action and the connection of the triggered signal is not in the same method.
    The context menu is shown in one slot, but it's created in another method with the actions.

    You cold also add a private member in MainWindow and remember it that way



  • I just noticed something, it returns the QModelIndex for the current right clicked item in the table, so when using QModelIndex::data it will return only the data of that item.

    I wanted to create one single context menu with something like:

    Copy Url to Clipboard
    Copy Title to Clipboard

    Url and Title are two different columns. I want that independently of the item I right click it appears the same context menu and copy the right item.



  • You can use index.model()->index(index.row(),URL_COLUMN,index.parent()).data() index.model()->index(index.row(),TITLE_COLUMN,index.parent()).data()



  • I did differently, as the user can only select one row, I used like this:

    auto selected = ui->resultsTableView->selectionModel()->selectedIndexes();
    

    In the QAction::triggered signal and this way I can do something like selected.at(0) to get the QModelIndex for the first column.

    Is there something wrong with that approach?



  • @Mr-Gisa said in QTableView context menu get QModelIndex information:

    Is there something wrong with that approach?

    I might be wrong here but I thought that if you right clicked on a item that it is not selected it does not get selected



  • Actually it does, if you right click on an unselected item it does get selected.


Log in to reply