PyQt5 中的 QListView.indexAt 返回错误的索引? [英] QListView.indexAt in PyQt5 returning wrong index?

查看:106
本文介绍了PyQt5 中的 QListView.indexAt 返回错误的索引?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当用户右键单击 QListView 中的一个项目时,我试图弹出一个上下文菜单,如果用户在任何项目(任何空格)之外单击鼠标右键,则会弹出一个不同的上下文菜单.我发现我在执行 indexAt 命令时收到的索引不准确,我不知道为什么.

I'm trying to pop up a context menu when a user right-clicks on an item in a QListView and a different context menu if the user right-clicks outside of any of the items (any of the whitespace). What I'm finding is that the index I'm receiving when performing the indexAt command is not accurate, and I can't figure out why.

我将 QListView 初始化为它自己的类:

I initialize the QListView as its own class:

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)

此时,列表为空.当打开文件以设置模型时,我还有其他功能,该模型将数据加载到屏幕上.

At this point, the list is empty. I have other functions when a file is opened to set the model, which loads the data on the screen.

这是我的 contextMenuEvent:

Here is my 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())

假设我有三个通用项目:

Let's assume I have three generic items:

  • item1
  • item2
  • item3

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

Thanks to the print statement, I can tell when I click the top 1/4 of item1 in the QListView, it is returning item1. If I click in the bottom 3/4 of item1, however, it is returning item2. Same logic for item2 and item3, only the bottom 3/4 of item3 returns None, hence returning the wrong context menu.

有人能帮我理解为什么会这样吗?我认为它与 event.pos() 有关,但我不知道是什么.

Can someone help me understand why this is happening? I'm thinking it has something to do with event.pos(), but I don't know what.

谢谢!!

推荐答案

event.pos() 的坐标是相对于拥有 contextMenuEvent() 的小部件的code> 方法,在您的情况下,它与窗口有关,但 indexAt() 方法需要相对于视图 (QListView) 的 viewport() 的坐标,所以您必须使用 mapFromGlobal() 方法进行转换:

The coordinates of the event.pos() are with respect to the widget that owns the contextMenuEvent() method, in your case it is with respect to the window but the indexAt() method expects coordinates with respect to the viewport() of the view(QListView) so You have to do a transformation using the mapFromGlobal() method:

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)

这篇关于PyQt5 中的 QListView.indexAt 返回错误的索引?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆