PyQt和上下文菜单

15

我需要在我的窗口上实现鼠标右键点击时创建一个上下文菜单。但我真的不知道如何实现。

是否有适用于此功能的小部件,或者我必须从头开始创建它?

编程语言:Python
图形库:Qt(PyQt)

2个回答

42

我不能代表Python,但在C++中这很容易。

首先,在创建小部件之后,您需要设置策略:

w->setContextMenuPolicy(Qt::CustomContextMenu);

然后你将上下文菜单事件连接到一个槽函数:

connect(w, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(ctxMenu(const QPoint &)));

最后,您实现插槽:

void A::ctxMenu(const QPoint &pos) {
    QMenu *menu = new QMenu;
    menu->addAction(tr("Test Item"), this, SLOT(test_slot()));
    menu->exec(w->mapToGlobal(pos));
}

这就是C++的做法,在Python API中应该不会有太大区别。

编辑:在Google上搜索后,以下是我在Python中示例设置部分的代码:

self.w = QWhatever();
self.w.setContextMenuPolicy(Qt.CustomContextMenu)
self.connect(self.w,SIGNAL('customContextMenuRequested(QPoint)'), self.ctxMenu)

1
请注意,在PyQt4中,CustomContextMenu的位置在此处:PyQt4.QtCore.Qt.CustomContextMenu。 - Jason Coon
2
两年和19个赞之后,突然来了一个随机的踩,真是让人爱不释手 :-P - Evan Teran
1
点踩是我不小心按错了,我非常非常抱歉。这个回答实际上帮了我很多。 - Vicky T
@UtkarshSinha 请查看http://meta.stackexchange.com/questions/127218/how-can-i-cancel-my-vote,它适用于取消踩票和赞票。简而言之:再次点击箭头即可。 - NuclearPeon

15

另一个示例展示了如何在工具栏和上下文菜单中使用操作。

class Foo( QtGui.QWidget ):

    def __init__(self):
        QtGui.QWidget.__init__(self, None)
        mainLayout = QtGui.QVBoxLayout()
        self.setLayout(mainLayout)

        # Toolbar
        toolbar = QtGui.QToolBar()
        mainLayout.addWidget(toolbar)

        # Action are added/created using the toolbar.addAction
        # which creates a QAction, and returns a pointer..
        # .. instead of myAct = new QAction().. toolbar.AddAction(myAct)
        # see also menu.addAction and others
        self.actionAdd = toolbar.addAction("New", self.on_action_add)
        self.actionEdit = toolbar.addAction("Edit", self.on_action_edit)
        self.actionDelete = toolbar.addAction("Delete", self.on_action_delete)
        self.actionDelete.setDisabled(True)

        # Tree
        self.tree = QtGui.QTreeView()
        mainLayout.addWidget(self.tree)
        self.tree.setContextMenuPolicy( Qt.CustomContextMenu )
        self.connect(self.tree, QtCore.SIGNAL('customContextMenuRequested(const QPoint&)'), self.on_context_menu)

        # Popup Menu is not visible, but we add actions from above
        self.popMenu = QtGui.QMenu( self )
        self.popMenu.addAction( self.actionEdit )
        self.popMenu.addAction( self.actionDelete )
        self.popMenu.addSeparator()
        self.popMenu.addAction( self.actionAdd )

    def on_context_menu(self, point):

         self.popMenu.exec_( self.tree.mapToGlobal(point) )

感谢@PedroMorgan提供的帮助-我在网上找到了一些使用“_SIGNAL(”customContextMenuRequest ... _“)的代码,不知道为什么它不起作用:) - 通过这篇文章,我现在知道它被称为customContextMenuRequested,末尾带有“ed”...干杯! - sdaau
我知道这是一个旧帖子,但PedroMorgan给出的示例对我不起作用。我在谷歌上进行了很多搜索,这是我找到的最接近的结果。当我右键单击列表时,我只会得到一个一像素大小的小框。有人能指向一个更近期的PyQt上下文菜单示例吗?最好像Pedro所演示的那样简单易懂。 - PrestonDocks
很久以前我已经记不得从哪里获取了可工作的代码,但最终我确实让我的代码运行起来了。谢谢。 - PrestonDocks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接