扩展QSpinBox ContextMenu

时间:2019-03-05 18:41:52

标签: python python-2.7 pyqt

感觉就像我到处都是,但是找不到答案。 想知道是否有办法将额外的QAction添加到QSpinBox ContextMenu吗? 理想情况下,是动作列表的顶部。

我知道您可以替换默认菜单,如下所示,但是可以弄清楚如何扩展:

import sys
from PyQt4 import QtGui, QtCore


class QSpinBox(QtGui.QSpinBox):
    def __init__(self, *args, **kargs):
        QtGui.QSpinBox.__init__(self, *args, **kargs)
        self.resize(200, 60)

        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.__contextMenu)

    def __contextMenu(self):
        self._normalMenu = self.build_menu()
        self._normalMenu.exec_(QtGui.QCursor.pos())

    def build_menu(self):
        self.menu = QtGui.QMenu(self)

        self.save = QtGui.QAction("Save", self)
        self.menu.addAction(self.save)

        self.reset = QtGui.QAction("Reset", self)
        self.menu.addAction(self.reset)

        return self.menu


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    form = QSpinBox()
    form.show()
    sys.exit(app.exec_())

默认菜单:

enter image description here

我想添加到顶部的选项:

enter image description here

在此先感谢您的帮助,

标记

1 个答案:

答案 0 :(得分:2)

诀窍是在QMenufindChild()一起显示QTimer.singleShot()的那一刻起

from PyQt4 import QtCore, QtGui

class SpinBox(QtGui.QSpinBox):
    def contextMenuEvent(self, event):
        QtCore.QTimer.singleShot(0, self.on_timeout)
        super(SpinBox, self).contextMenuEvent(event)

    @QtCore.pyqtSlot()
    def on_timeout(self):
        menu = self.findChild(QtGui.QMenu, 'qt_edit_menu')
        if menu is not None:
            first_action = menu.actionAt(QtCore.QPoint())
            save_action = QtGui.QAction(
                "Save", 
                menu, 
                shortcut=QtGui.QKeySequence.Save,
                triggered=self.on_save_triggered
            )
            reset_action = QtGui.QAction(
                "Reset", 
                menu, 
                triggered=self.on_reset_triggered
            )
            menu.insertAction(first_action, save_action)
            menu.insertAction(save_action, reset_action)
            menu.insertSeparator(first_action)

    @QtCore.pyqtSlot()
    def on_save_triggered(self):
        print("save")

    @QtCore.pyqtSlot()
    def on_reset_triggered(self):
        print("reset")

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    w = SpinBox()
    w.resize(600, w.sizeHint().height())
    w.show()
    sys.exit(app.exec_())