我有一个嵌套的菜单项,试图将所有这些项都选中。最初,切换不适用于主要项目(设置为QAction的QMenu),而适用于子项目。
但是使用mousePressEvent
时,切换现在适用于主要项目,但不适用于子项目。
试图为子项功能复制我对主项所做的操作,但是切换仍然不起作用。貌似,它在_callActionItem()
中被两次调用。
但是,由于某些原因,如果子项目窗口处于撕开模式,则可以切换,但如果不能在工具本身中单击鼠标右键,则无法切换。
另外,如果我在mousePressEvent
中禁用了QCustomMenu
,我将回到第一个方框,这里的切换适用于子项,而不适用于主项
class QSubAction(QtGui.QAction):
def __init__(self, text="", parent=None):
super(QSubAction, self).__init__(text, parent)
self.setCheckable(True)
self.setChecked(True)
class QAddAction(QtGui.QAction):
def __init__(self, icon=None, text="Add Item", parent=None):
if icon:
super(QAddAction, self).__init__(icon, text, parent)
else:
super(QAddAction, self).__init__(text, parent)
class QCustomMenu(QtGui.QMenu):
"""Customized QMenu."""
def __init__(self, title, parent=None):
super(QCustomMenu, self).__init__(title=str(title), parent=parent)
self.setup_menu()
def mousePressEvent(self, event):
action = self.activeAction()
if isinstance(action, QtGui.QAction):
action.trigger()
return QtGui.QMenu.mousePressEvent(self, event)
def setup_menu(self):
self.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu)
def contextMenuEvent(self, event):
no_right_click = [QAddAction]
if any([isinstance(self.actionAt(event.pos()), instance) for instance in no_right_click]):
return
pos = event.pos()
def addAction(self, action):
super(QCustomMenu, self).addAction(action)
class Example(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Example, self).__init__(parent)
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 300, 200)
self.setWindowTitle('Context menu')
self.qmenu = QCustomMenu(title='', parent=self)
add_item_action = QtGui.QAction('Add Main item', self,
triggered=self.add_new_item)
self.qmenu.addAction(add_item_action)
def contextMenuEvent(self, event):
action = self.qmenu.exec_(self.mapToGlobal(event.pos()))
def add_new_item(self):
main_menu_name, ok = QtGui.QInputDialog.getText(
self,
'Main Menu',
'Name of new Menu Item:'
)
if ok:
self._addMenuItemTest(main_menu_name)
def _addMenuItemTest(self, main_menu_name):
icon_path = '/user_data/add.png'
base_qmenu = QCustomMenu(title=main_menu_name, parent=self)
base_qmenu.setTearOffEnabled(True)
add_item_action = QAddAction(None, 'Add Sub Item', base_qmenu)
slot = functools.partial(self.add_sub_item, base_qmenu)
add_item_action.triggered.connect(slot)
base_qmenu.addAction(add_item_action)
test_action = QtGui.QAction(main_menu_name, self)
test_action.setMenu(base_qmenu)
test_action.setCheckable(True)
test_action.setChecked(True)
self.connect(
test_action,
QtCore.SIGNAL("triggered(bool)"),
self.main_toggling
)
self.qmenu.addAction(test_action)
def main_toggling(self, check_state):
sender_obj = self.sender()
if isinstance(sender_obj, QtGui.QAction):
sender_obj.setChecked(check_state)
def add_sub_item(self, base_menu):
sub_menu_name, ok = QtGui.QInputDialog.getText(
self,
'Sub Menu',
'Name of new Sub Item:'
)
if ok:
action = QSubAction(sub_menu_name, self)
slot = functools.partial(
self._callActionItem,
action
)
# action.toggled.connect(slot)
# from pprint import pprint
# pprint(help(action))
# action.connect(action, QtCore.SIGNAL("triggered(bool)"), self._callActionItem)
base_menu.addAction(action)
def _callActionItem(self, action):
# This is called twice, False and True again
print '>>> sub check-state : ', action.isChecked()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = Example()
window.show()
sys.exit(app.exec_())
答案 0 :(得分:1)
默认情况下,QMenu只会使没有子项的QAction可以检查,因此您做了一个技巧来启用另一个不符合上述要求的QAction的功能,这可能会影响操作,这就是您所遇到的情况。解决方案是区分按下了哪种类型的QAction:
def mousePressEvent(self, event):
action = self.activeAction()
if not isinstance(action, QSubAction) and action is not None:
action.trigger()
return
return QtGui.QMenu.mousePressEvent(self, event)
答案 1 :(得分:1)
QtGui.QAction.toggle() 这是checked()属性的便捷功能。连接到它以将选中状态更改为相反状态。
和
如果我执行您的代码,则发生TypeError。 (添加子菜单后,单击子菜单操作项)
<?xml version="1.0" encoding="utf-8"?>
<svg id="svg02" class="svg02" x="0px" y="0px" viewBox="0 0 575.2 481.5" style="position: absolute; top: 0; left: 0;" xml:space="preserve">
<clipPath id="clip01">
<polygon class="st0 line01" points="212.1,0.7 212.1,175.5 434.9,85.2 " />
</clipPath>
<image class="image_01" xlink:href="img/bg_01.jpg" x="-200" y="0" width="1000" height="500" style="clip-path: url(#clip01);" />
<image class="image_02" xlink:href="img/bg_01.jpg" x="-200" y="0" width="1000" height="500" style="clip-path: url(#clip01);" />
</svg>
<script>
var imgChange = function() {
var i = 1;
function changeBackground() {
$(".image_02")
.hide()
.fadeIn();
if (i > 5) {
i = 1;
}
document
.querySelector(".image_01")
.setAttributeNS(
"http://www.w3.org/1999/xlink",
"xlink:href",
"img/bg_0" + (i - 1) + ".jpg"
);
document
.querySelector(".image_02")
.setAttributeNS(
"http://www.w3.org/1999/xlink",
"xlink:href",
"img/bg_0" + i + ".jpg"
);
i++;
}
setInterval(changeBackground, 3000);
};
imgChange();
</script>
似乎您为_callActionItem()准备了丰富的参数。
但这是一个陷阱。
因为切换需要TypeError: _callActionItem() takes 3 positional arguments but 4 were given
的参数。
因此,您必须将_callActionItem()的参数更改为bool
和_callActionItem(self,checked,action)
在toggled
之后。
toggling
调用toggle
。
例如,您更改QSubAction
。
1。
mousePressEvent
和
2。
def mousePressEvent(self,event):
action = self.activeAction()
if not isinstance(action,QSubAction) and action is not None:
action.trigger()
return
elif isinstance(action,QSubAction):
action.toggle()
return
return QtGui.QMenu.mousePressEvent(self,event)
以及此处所有已更改的代码。
_callActionItem(self,checked,action)