从字符串PyQt - QtDesigner - Maya列表中的许多按钮上创建contextMenu

时间:2014-05-02 21:09:10

标签: pyqt contextmenu designer maya

我正在尝试为我正在制作的maya UI中的许多不同按钮创建相当多的contextMenu。

问题是我有很长的按钮列表,我需要相同的contextMenu。我现在所做的并不是很优雅,这就是为什么我在问你是否可以帮助我。

因为使用以下过程,我的脚本会很长,但我无法弄清楚如何正确清理它。

以下是我的代码示例:

from PyQt4 import QtCore,QtGui,uic
from functools import partial
import os


class MyWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        uiFilePath = os.path.join(os.path.dirname(__file__),"myfile.ui") 
        self.ui = uic.loadUi(uiFilePath, self)

        '''
        Right Click Menu
        '''
        self.ui.buttonA.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.ui.buttonA.customContextMenuRequested.connect(self.buttonAMenu)

        self.ui.buttonB.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.ui.buttonB.customContextMenuRequested.connect(self.buttonBMenu)


    '''
    BUTTON A
    '''
    @QtCore.pyqtSlot()
    def on_buttonA_released(self):
        print ('Doing Stuff when clicking on Button A')

    def buttonAMenu(self, pos):
        menu = QtGui.QMenu()
        menu.addAction('First Action', lambda:self.FirstActionButtonA(objects))
        menu.addAction('Second Action', lambda:self.SecondActionButtonA(objects))
        menu.exec_(QtGui.QCursor.pos())

    def FirstActionButtonA(self, objects):
        print ('First Action working on :')
        print (objects)

    def SecondActionButtonA(self):
        print ('Second Action working on :')
        print (objects)

    '''
    BUTTON B
    '''
    @QtCore.pyqtSlot()
    def on_buttonB_released(self):
        print ('Doing Stuff when clicking on Button B')

    def buttonBMenu(self, pos):
        menu = QtGui.QMenu()
        menu.addAction('First Action', lambda:self.FirstActionButtonB(objects))
        menu.addAction('Second Action', lambda:self.SecondActionButtonB(objects))
        menu.exec_(QtGui.QCursor.pos())

    def FirstActionButtonB(self, objects):
        print ('First Action working on :')
        print (objects)

    def SecondActionButtonB(self):
        print ('Second Action working on :')
        print (objects)

2 个答案:

答案 0 :(得分:1)

所以你要做的是创建一个包含代码的类。您可以为每个按钮或每个按钮创建此类的实例。这两个选项是:

  • 创建一个在实例化时传递给按钮的引用的类。这是最简单但技术上不太干净的方法。
  • 子类QPushButton并将Qt Designer中的按钮提升为新类

请注意,首选解决方案是子类QPushButton,然后将Qt Designer中的小部件升级到新类。然而,这可能有点繁琐。但是,如果你想沿着这条路走下去,你可以,而且你想读这个:Promote PyQt Widget

无论哪种方式,这个类看起来都很相似。你会想要这样的东西(对于选项1)

class MyButton(object):
    def __init__(self, button):
        self.button = button
        self.button.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.button.customContextMenuRequested.connect(self.buttonMenu)
        self.button.clicked.connect(self.on_button_released)

    @QtCore.pyqtSlot()
    def on_button_released(self):
        print ('Doing Stuff when clicking on Button A')

    def buttonMenu(self, pos):
        menu = QtGui.QMenu()
        menu.addAction('First Action', lambda:self.FirstActionButton(objects))
        menu.addAction('Second Action', lambda:self.SecondActionButton(objects))
        menu.exec_(QtGui.QCursor.pos())

    def FirstActionButton(self, objects):
        print ('First Action working on :')
        print (objects)

    def SecondActionButton(self):
        print ('Second Action working on :')
        print (objects)

您的MyWidget课程将如下:

class MyWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        uiFilePath = os.path.join(os.path.dirname(__file__),"myfile.ui") 
        self.ui = uic.loadUi(uiFilePath, self)

        list_of_buttons = [self.ui.buttonA, self.ui.buttonB,...]
        self.adaptors = []
        for button in list_of_buttons:
            self.adapters.append(MyButton(button))

对于选项2,您希望将班级更改为:

class MyButton(QtGui.QPushButton):
    def __init__(self, *args, **kwargs):
        QPushButton.__init__(self,*args,**kwargs)
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.buttonMenu)
        self.clicked.connect(self.on_button_released)

    # same code follows as in above class example

如果小部件促销正确完成,您不需要在__init__类的MyWidget方法中执行任何特殊操作,因为当您调用{{uic.loadUI时,您的自定义类将自动实例化1}}。

答案 1 :(得分:0)

如果您的按钮功能完全相同(例如按钮名称除外),您可以将所有25个按钮信号发送到同一个插槽,并在该插槽中使用self.sender().objectName(或类似)。虽然有些开发人员不喜欢使用self.sender(),但这是PyQt书中描述的一种成熟的技术(使用Python和Qt进行快速GUI编程)。