我试图在用户右键单击QListView中的项目时弹出上下文菜单,如果用户在任何项目(任何空格)之外单击鼠标右键,则要弹出另一个上下文菜单。我发现执行indexAt命令时收到的索引不正确,我无法弄清原因。
我将QListView初始化为其自己的类:
class RBKDataTypesTab(QWidget):
def __init__(self):
super().__init__()
self.models = []
grid = QGridLayout()
self.list = QListView()
self.list.clicked.connect(self.list_item_selected)
grid.addWidget(self.list, 0, 0, -1, 8)
self.table = QTableView()
self.indexMenu = QMenu()
self.indexMenu.addAction('Add DataType', self.addDataType)
self.indexMenu.addAction('Remove DataType', self.removeDataType)
self.nonIndexMenu = QMenu()
self.nonIndexMenu.addAction('Add DataType', self.addDataType)
grid.addWidget(self.table, 0, 2, -1, -1)
self.setLayout(grid)
此时,列表为空。打开文件设置模型时,我还有其他功能,该模型将数据加载到屏幕上。
这是我的contextMenuEvent:
def contextMenuEvent(self, event):
index = self.list.indexAt(event.pos())
print(index.data())
if(index.isValid()):
event.accept()
self.indexMenu.exec_(event.globalPos())
else:
event.accept()
self.nonIndexMenu.exec_(event.globalPos())
假设我有三个通用项目:
由于打印语句,我可以知道当我单击QListView中item1的顶部1/4时,它正在返回item1。但是,如果我单击item1的底部3/4,它将返回item2。 item2和item3的逻辑相同,只有item3的底部3/4返回None,因此返回错误的上下文菜单。
有人可以帮助我了解为什么会这样吗?我在想它与event.pos()有关,但我不知道是什么。
谢谢!
event.pos()
的坐标是相对于拥有contextMenuEvent()
方法的小部件的,在您的情况下,它是相对于窗口的,但是indexAt()
方法期望的是相对于窗口viewport()
的坐标view(QListView),所以您必须使用mapFromGlobal()
方法进行转换:
def contextMenuEvent(self, event):
gp = event.globalPos()
lp = self.list.viewport().mapFromGlobal(gp)
index = self.list.indexAt(lp)
if index.isValid():
self.indexMenu.exec_(gp)
else:
self.nonIndexMenu.exec_(gp)