I have a simple pyside QMenu which is being populated with QActions when the application starts. Each menu action represents a class object. How can I create a new instance of the class object based on the Menu Item clicked, and append that new object to a list, which in this example is called
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()
the exec_()
method of QMenu
returns the selected QAction
, through that QAction
that is a MyAction
that has as attribute ui
that gives us the associated Barker object, using the Barker we can access the class through __class__
and create another one object:
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)