上下文菜单在不应该打开的时候打开(if...elif)
Context menu is opening when it shouln't (if...elif)
我有一个包含 8 列的 QTableWidget,我希望上下文菜单仅在第一列(第 0 列)中打开,因为在其余列中我使用右键单击进行不同的操作。
当我第一次启动程序时,一切正常:例如,如果我先在第 3 列的单元格中单击鼠标右键,它会执行它应该执行的操作(从单元格值中减去 1),但它不会打开上下文菜单,完美。
但是在我首先右键单击第 0 列以打开上下文菜单(它工作正常)之后,如果我返回到第 3 列并右键单击...上下文菜单打开!它也执行它应该执行的操作(从单元格值中减去 1)!
这是我使用的代码:
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))
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()
将事件处理程序 (on_context_menu
) 连接到另一个事件处理程序 (mousePressEvent
) 中的事件 (customContextMenuRequested
) 似乎是非正统的。
相反,您可以在 __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
部分。
我有一个包含 8 列的 QTableWidget,我希望上下文菜单仅在第一列(第 0 列)中打开,因为在其余列中我使用右键单击进行不同的操作。
当我第一次启动程序时,一切正常:例如,如果我先在第 3 列的单元格中单击鼠标右键,它会执行它应该执行的操作(从单元格值中减去 1),但它不会打开上下文菜单,完美。
但是在我首先右键单击第 0 列以打开上下文菜单(它工作正常)之后,如果我返回到第 3 列并右键单击...上下文菜单打开!它也执行它应该执行的操作(从单元格值中减去 1)!
这是我使用的代码:
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))
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()
将事件处理程序 (on_context_menu
) 连接到另一个事件处理程序 (mousePressEvent
) 中的事件 (customContextMenuRequested
) 似乎是非正统的。
相反,您可以在 __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
部分。