Qt RightClick на QListWidget открывает контекстное меню и удаляет элемент

Я хочу знать, как я могу открыть всплывающее меню, когда я щелкаю правой кнопкой мыши по элементам таблицы. Во всплывающем меню должны быть указаны некоторые действия, такие как добавление и удаление, которые создадут новую строку или удалят выбранную строку.

Я новичок в мире Qt, поэтому если кто-нибудь сможет дать мне полную информацию (с кодом, если это возможно), то я буду очень благодарен ему/ей.

Спасибо.

Моя цель: только в области QListWidget и только если вы нажмете на элемент, откроется меню с Удалить.


Изменить: Хорошо, я решил проблему с QListWidget и меню. Теперь необходимо выполнить следующее:

Если щелкнуть правой кнопкой мыши по элементу, а затем нажать "Удалить", элемент будет удален.

Мой код:


void ProvideContextMenu(const QPoint &); // MainWindow.h
// In MainWindow.cpp

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

void MainWindow::ProvideContextMenu(const QPoint &pos)
{
    QPoint item = ui->listFiles->mapToGlobal(pos);
    QMenu submenu;
    submenu.addAction("ADD");
    submenu.addAction("Delete");
    QAction* rightClickItem = submenu.exec(item);
    if (rightClickItem && rightClickItem->text().contains("Delete") )
    {
        ui->listFiles->takeItem(ui->listFiles->indexAt(pos).row());
    }
}

Edit2: хорошо, я решил всю проблему: D. Я загрузил свой код, если кому-то нужно что-то подобное, это может помочь ему/ей.

Ответ 1

Во-первых, вам нужно создать слот для открытия контекстного меню:

void showContextMenu(const QPoint&);

В конструкторе вашего класса, который использовал QListWidget, установить политику контекстного меню для настройки и подключения сигнала QListWidget::customContextMenuRequested(QPoint) и слота showContextMenu() следующим образом:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    setupUi(this);

    listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(listWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint)));
}

Затем нужно реализовать открытие контекстного меню:

void MainWindow::showContextMenu(const QPoint &pos)
{
    // Handle global position
    QPoint globalPos = listWidget->mapToGlobal(pos);

    // Create menu and insert some actions
    QMenu myMenu;
    myMenu.addAction("Insert", this, SLOT(addItem()));
    myMenu.addAction("Erase",  this, SLOT(eraseItem()));

    // Show context menu at handling position
    myMenu.exec(globalPos);
}

После этого нам нужно реализовать слоты для добавления и удаления элементов QListWidget:

void MainWindow::eraseItem()
{
    // If multiple selection is on, we need to erase all selected items
    for (int i = 0; i < listWidget->selectedItems().size(); ++i) {
        // Get curent item on selected row
        QListWidgetItem *item = listWidget->takeItem(listWidget->currentRow());
        // And remove it
        delete item;
    }
}

Как вы можете видеть, мы перебираем все выбранные элементы (для установки режима множественного выбора используйте метод setSelectionMode()) и удаляем его сами, потому что docs говорит, что

Элементы, удаленные из виджета списка, не будут управляться Qt и будут необходимо удалить вручную.

Добавление некоторых элементов проще, мое решение со статической переменной для разных заголовков элементов выглядит следующим образом:

void MainWindow::addItem()
 {
        static int i = 0;
        listWidget->addItem(QString::number(++i));
 }

Чтобы упростить код, используйте Qt5 sytax для сигналов и слотов. Это устраняет необходимость создания промежуточных слотов.

Я надеюсь, что это поможет вам.