【发布时间】:2013-12-24 21:06:18
【问题描述】:
UPDATE 已编辑以添加示例并修剪一些内容。 (请重新打开?)
Python 的 Qt 实现 PyQt 一直很好地为我服务,但它的某些方面仍然让我很困惑。
现在我遇到了一个问题,即默认触发的事件与我不希望它们触发的事件以及无法区分我想要触发的事件和我不想触发的事件。
我正在构建一个上下文菜单,当您单击现有操作时,它会在其中弹出新操作。下面以伪代码为例:
from PyQt4 import QtGui,QtCore
class MainWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.menubar = QtGui.QMenuBar(self)
self.setMenuBar(self.menubar)
self.menu = MyMenu(self)
self.menubar.addAction(self.menu.menuAction())
self.menu.setTitle('Menu')
self.listy = []
self.installEventFilter(self.eventFilter)
class MyMenu(QtGui.QMenu):
def __init__(self,parent=None):
QtGui.QMenu.__init__(self)
self.quit_action = QtGui.QAction("Close",self)
self.add_action = QtGui.QAction("Add action",self)
self.new_action = QtGui.QAction(" New action",self)
self.new_action.setVisible(False)
self.add_action.triggered.connect(self.toggleActionOn)
for i in self.quit_action,self.add_action,self.new_action:
self.addAction(i)
self.installEventFilter(self)
def toggleActionOn(self):
self.new_action.setVisible(True)
它很好用,除了我设置了一个竞争条件:只要我点击一个动作,菜单就会自动关闭。由于这些内置触发器妨碍了我自己的触发器,我想阻止它们发生。
我尝试拦截关闭和鼠标释放事件:
class MyMenu(QtGui.QMenu):
def closeEvent(self,event):
...
event.accept()
...
def mouseReleaseEvent(self,event):
...
event.accept()
...
...这似乎没用,因为收到的事件没有关于发件人的信息。但是它确实告诉了我在 QMenu 中单击导致的事件顺序:MouseButtonPress、Close、Hide、HideToParent、Enter、Leave。
我添加了eventFilter:
class MyMenu(QtGui.QMenu):
...
def eventFilter(self, obj, event):
print 'EVENT RECEIVED'
print obj, event
if ( obj is self or obj is self.new_action ) and event.type() == QtCore.QEvent.Close:
return True
else:
return False
给出的“事件”没有任何元素告诉我“关闭”的发送者是什么。
在绝望中,我试图断开动作,new_action.disconnect(QtCore.QEvent.Close),以及其他类似的荒谬策略。
有谁知道如何将对象与其相关的“关闭”事件“断开”,或者如何更有选择地禁止关闭事件发生??
更新 正如 Pavel Strakhov 指出的那样,问题在于我对事件处理的误解。为了阻止QMenu.Close 通过,我必须过滤原始事件@987654333@ 或MousePressEvent,它启动了事件链,它恰好归因于我需要识别的QAction 的位置.
【问题讨论】:
-
请剪掉文字墙,贴一些实际代码。