PyQt5中的QListView.indexAt返回错误的索引?

问题描述 投票:0回答:1

我试图在用户右键单击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())

假设我有三个通用项目:

  • item1
  • item2
  • item3

由于打印语句,我可以知道当我单击QListView中item1的顶部1/4时,它正在返回item1。但是,如果我单击item1的底部3/4,它将返回item2。 item2和item3的逻辑相同,只有item3的底部3/4返回None,因此返回错误的上下文菜单。

有人可以帮助我了解为什么会这样吗?我在想它与event.pos()有关,但我不知道是什么。

谢谢!

python pyqt pyqt5 qlistview
1个回答
0
投票

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)
© www.soinside.com 2019 - 2024. All rights reserved.