动态创建的 QActions 创建 class 对象

Dynamically created QActions creating class object

我有一个简单的 pyside QMenu,它在应用程序启动时被 QActions 填充。每个菜单操作代表一个 class 对象。如何根据单击的菜单项创建 class 对象的新实例,并将该新对象附加到列表中,在此示例中称为

ACTIVE_BAKERS = []

import sys
from PySide import QtGui, QtCore

################################################################################
# Bakers
################################################################################
class Baker(QtGui.QWidget):
    def __init__(self, name):
        self.name = name


class Baker_John(Baker):
    def __init__(self):
        Baker.__init__(self, name='John')


class Baker_Amy(Baker):
    def __init__(self):
        Baker.__init__(self, name='Amy')


class Baker_Makela(Baker):
    def __init__(self):
        Baker.__init__(self, name='Makela')


class Baker_Jeff(Baker):
    def __init__(self):
        Baker.__init__(self, name='Jeff')


################################################################################
# Action
################################################################################
class MyAction(QtGui.QAction):

    on_action = QtCore.Signal(dict)

    def __init__(self, user_info, *args, **kwargs):
        super(MyAction, self).__init__(*args, **kwargs)
        self.ui = user_info
        self.triggered.connect(self.on_triggered)

    def on_triggered(self):
        print('UI:', self.ui)
        self.on_action.emit(self.ui)


class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.resize(200, 300)

        # OBJECTS - variable containing list of class objects created
        ACTIVE_BAKERS = []

        # CONTROLS
        self.ui_items = QtGui.QListView()
        self.ui_items.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.ui_items.customContextMenuRequested.connect(self.open_tasks_contextmenu)
        self.setCentralWidget(self.ui_items)
        self.create_context_menu_ui()


    # dynamically create the menu
    def create_context_menu_ui(self):
        self.add_baker = QtGui.QMenu("Add")

        AVAILABLE_BAKERS = [Baker_John(), Baker_Amy(), Baker_Makela(), Baker_Jeff()]
        for x in AVAILABLE_BAKERS:
            new_action = MyAction(x, x.name, self)
            self.add_baker.addAction(new_action)

        self._cmenu = QtGui.QMenu()
        self._cmenu.addMenu(self.add_baker)


    def open_tasks_contextmenu(self, position):
        self._cmenu.exec_(QtGui.QCursor.pos())


def main():
    app = QtGui.QApplication(sys.argv)
    ex = MainWindow()
    ex.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

QMenu returns 所选择的 QActionexec_() 方法,通过 QAction 即具有 as 属性的 MyAction ui 为我们提供了关联的 Barker 对象,使用 Barker 我们可以通过 __class__ 访问 class 并创建另一个对象:

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.resize(200, 300)

        # OBJECTS - variable containing list of class objects created
        self.ACTIVE_BAKERS = []

        # CONTROLS
        self.ui_items = QtGui.QListView()
        self.ui_items.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.ui_items.customContextMenuRequested.connect(self.open_tasks_contextmenu)
        self.setCentralWidget(self.ui_items)
        self.create_context_menu_ui()


    # dynamically create the menu
    def create_context_menu_ui(self):
        self.add_baker = QtGui.QMenu("Add")

        AVAILABLE_BAKERS = [Baker_John(), Baker_Amy(), Baker_Makela(), Baker_Jeff()]
        for x in AVAILABLE_BAKERS:
            new_action = MyAction(x, x.name, self)
            self.add_baker.addAction(new_action)

        self._cmenu = QtGui.QMenu()
        self._cmenu.addMenu(self.add_baker)


    def open_tasks_contextmenu(self, position):
        action = self._cmenu.exec_(QtGui.QCursor.pos())
        if isinstance(action, MyAction):
            obj = action.ui.__class__()
            if obj not in self.ACTIVE_BAKERS:
                self.ACTIVE_BAKERS.append(obj)