上下文菜单在它不起作用时打开(如果...... elif)

时间:2018-06-06 10:44:46

标签: python pyqt contextmenu pyqt5

我有一个包含8列的QTableWidget,我希望上下文菜单只在第一列(第0列)中打开,因为在其余列中我使用右键单击进行不同的操作。

当我第一次启动程序时,一切都按预期工作:如果我在第3列的单元格中右键单击,例如它执行它应该做的事情(从单元格值中减去1)并且它不会打开上下文菜单,完美。

但是我在右键单击第0列后首先打开上下文菜单(它工作正常),如果我回到第3列并右键单击...上下文菜单打开!它也会做它应该做的动作(从单元格值减去一个)!

以下是我正在使用的代码:

class Table(QtWidgets.QTableWidget):
            cellExited = QtCore.pyqtSignal(int, int)
            itemExited = QtCore.pyqtSignal(QtWidgets.QTableWidgetItem)

    def __init__(self,*args,**kwargs):
            QtWidgets.QTableWidget.__init__(self,*args,**kwargs)
            self.setItemDelegate(ReadOnlyDelegate(self))
            self._last_index = QtCore.QPersistentModelIndex()
            self.viewport().installEventFilter(self)
            self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)

            self.popMenu = QtWidgets.QMenu(self)
            self.popMenu.addAction(QtWidgets.QAction('Action 1', self))
            self.popMenu.addAction(QtWidgets.QAction('Action 2', self))
            self.popMenu.addAction(QtWidgets.QAction('Action 3', self))

    def mousePressEvent(self,event):
        it = self.itemAt(event.pos())
        print(it.column())    #DEBUG
        if it.column()>0:
            if event.button() == QtCore.Qt.LeftButton:
                it.setText(str(round(float(it.text()) + 1,2)))
            elif event.button() == QtCore.Qt.RightButton:
                it.setText(str(round(float(it.text()) - 1,2)))
        elif it.column() == 0 and event.button() == QtCore.Qt.RightButton:
            print(it.column() == 0)    #DEBUG
            print(event.button() == QtCore.Qt.RightButton)    #DEBUG        
            self.customContextMenuRequested.connect(self.on_context_menu)

    def on_context_menu(self, point):
        self.popMenu.exec_(self.viewport().mapToGlobal(point))

2 个答案:

答案 0 :(得分:0)

self.customContextMenuRequested.connect(self.on_context_menu)表示您将事件customContextMenuRequested与方法self.on_context_menu相关联。每次事件发生时(每次都可能出现右键单击),将调用该方法。

第一次右键单击第0列时,将事件连接到方法。从那时起,每次右键单击都会调用该方法。

你想要的是直接调用self.on_context_menu,如:

def mousePressEvent(...):
   ....
   elif it.column() == 0 ... :
        self.on_context_menu()

答案 1 :(得分:0)

将事件处理程序(on_context_menu)连接到另一个事件处理程序(customContextMenuRequested)中的事件(mousePressEvent)似乎是非正统的。

相反,您可以使用__init__方法连接事件。这意味着将self.customContextMenuRequested.connect(self.on_context_menu)移至__init__。 然后在on_context_menu中,您应该检查请求的上下文菜单,如果它是第一列,则只显示它:

def on_context_menu(self, point):
    # the ... should be replaced by code that gets the column on which the event occurred
    column == ...
    if column == 0:
        self.popMenu.exec_(self.viewport().mapToGlobal(point))

(我实际上并不知道如何在on_context_menu

中找到列

然后在mousePressEvent内,您不再需要整个elif部分。