Как в QListWidget отслеживать нажатие на элементы правой кнопкой мыши (ПКМ)?

Как можно сделать так, что если пользователь будет нажимать ПКМ по объекту из QListWidget, то у него будет выбор удалить объект?

Пытался сделать так:

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QListWidget, QListWidgetItem, QMenu
from PyQt6.QtGui import QAction


class App(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("PyQt6")

        self.qlist_widget = QListWidget(self)
        self.qlist_widget.setGeometry(500, 45, 555, 200)
        self.qlist_widget.addItem(QListWidgetItem("bello"))
        self.qlist_widget.itemClicked.connect(self.show_context_menu)
        
        self.menu = QMenu(self)
        self.menu.addAction(QAction("Удалить", self.qlist_widget))
       
    def show_context_menu(self, position, item):
        self.qlist_widget.takeItem(item)
        self.menu.exec(self.qlist_widget.mapToGlobal(position))
        
        
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = App()
    window.show()
    app.exec()

Но, к сожалению, оно не работает.
Есть ли какое-то решение этой проблемы?


Ответы (1 шт):

Автор решения: S. Nick

Как вариант, используя фильтр событий:

import sys
'''
from PyQt6.QtWidgets import QApplication, QMainWindow, \
    QListWidget, QListWidgetItem, QMenu
from PyQt6.QtGui import QAction
'''
from PyQt5.QtWidgets import QApplication, QMainWindow, \
    QListWidget, QListWidgetItem, QMenu, QAction, \
    QWidget, QVBoxLayout
from PyQt5. QtCore import QEvent, QTimer


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.centralWidget = QWidget()                          # +++
        self.setCentralWidget(self.centralWidget)               # +++
        self.item = None                                        # +++
        self.row = None                                         # +++

        self.qlist_widget = QListWidget(self)
#        self.qlist_widget.addItem(QListWidgetItem("bello"))
        self.qlist_widget.addItems(                             # +++
            ('bello', 'Facebook', 'Microsoft', 'Google'))       # +++

        self.qlist_widget.itemClicked.connect(
            self.show_context_menu)
        self.qlist_widget.installEventFilter(self)              # !!! +++
        
        self.layout = QVBoxLayout(self.centralWidget)           # +++
        self.layout.addWidget(self.qlist_widget)                # +++

    def eventFilter(self, source, event):                       # +++
        if event.type() == QEvent.ContextMenu and \
            source.itemAt(event.pos()):
            
            menu = QMenu()
            menu.addAction('Удалить')
            menu.triggered.connect(self.selected)               # +++
      
            if menu.exec_(event.globalPos()):
                self.item = source.itemAt(event.pos())
                self.row = source.indexFromItem(
                    source.currentItem()).row()
            return True
        return super().eventFilter(source, event)
            
    def selected(self, q):
#        print(f'\nq={q}---{self.item}--------') #
#        self.q = q.text()
        QTimer.singleShot(10, self.del_selected)

    def del_selected(self):
        if not self.row is None:
            item = self.qlist_widget.takeItem(self.row)
            del item                                         # !!! +++
    
#    def show_context_menu(self, position, item):
    def show_context_menu(self, item):
        print(f'item={item.text()}; '
              f'строка={self.qlist_widget.currentRow()}') 
    
        
if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setStyleSheet('''
        QWidget {
            font-size: 30px;
        }
    ''')
    window = MainWindow()
    window.setWindowTitle("Контекстное меню в QListWidget")
    window.resize(600, 300)
    window.show()
    sys.exit(app.exec())

введите сюда описание изображения

введите сюда описание изображения

→ Ссылка