Good evening, and a happy new year you all.
I'm working on a GUI that is expected to become larger and larger in the future, so I am aiming to make it as scalable as possible.
For this purpose, I created a custom class which should handle all default actions in my app at once:
The whole point of doing all this was having an object that drops all my actions ready-to-use in my app, icons included, so this is a pretty fundamental part of the whole thing. I really can't figure out how to work this out.
Any help would be greatly appreciated. Also, I would like to have an opinion by more seasoned developers whether this approach is acceptable, if it goes against some conventions or best practices, or generally if this looks something that makes sense doing or not.
I am used to Swift features like extension, delegate and others that I still miss sometimes in Python (perhaps because I still have to understand the mechanism deeply).
I'm working on a GUI that is expected to become larger and larger in the future, so I am aiming to make it as scalable as possible.
For this purpose, I created a custom class which should handle all default actions in my app at once:
from typing import List from collections import namedtuple from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import (QApplication, QAction, QStyle) class JHActionSet(QAction, QStyle): ''' Implements and handles default actions in a J*** H*** view. ''' def __init__(self): super(JHActionSet, self).__init__() self.defaults() def defaults(self): action = namedtuple('Action', ['icon', 'text', 'method', 'tooltip']) # TODO : Consider adding 'shortcut' field and implement regional settings. # Default methods declaration def foo(): print("Hello, world") # Default actions declaration # TODO : Must implement regional settings, for now hardcoded str are ok return { 'research': action('ico/research.png', 'Ricerca', foo, '...'), 'selection': action(QStyle.SP_MessageBoxInformation, 'Selezione', foo, '...'), 'composition': action(QStyle.SP_MessageBoxInformation, 'Composizione', foo, '...'), 'infopane': action(QStyle.SP_MessageBoxInformation, 'Dettagli', foo, '...') } def get(self, request): actions = self.defaults() try: data = self.defaults()[request] action_ = QAction(text=data.text) action_.setToolTip(data.tooltip) action_.setIcon(QIcon(data.icon)) action_.triggered.connect(data.method) return action_ except ValueError: raise ValueError("You requested a JHAction that is not supported.") def get_set(self) -> List[QAction]: action_set = [] for key in self.defaults(): action_set.append(self.get(key)) return action_setSo basically, in order to implement my let's call it "default actions pack" in the final app, I should simply initialise the class and get the actions ready to use:
actions = JHActionSet().get_set() # -> A list of all my actions for action in self.actions: self.toolbar.addAction(action)Everything works as expected, except setting the actions' icons. If I comment out line #39 code works flawlessly, but as it is now it throws this exception:
Output:QPixmap: Must construct a QGuiApplication before a QPixmap
I tried to pass a string instead of a QIcon() object but it raises a TypeError
instead. The whole point of doing all this was having an object that drops all my actions ready-to-use in my app, icons included, so this is a pretty fundamental part of the whole thing. I really can't figure out how to work this out.
Any help would be greatly appreciated. Also, I would like to have an opinion by more seasoned developers whether this approach is acceptable, if it goes against some conventions or best practices, or generally if this looks something that makes sense doing or not.
I am used to Swift features like extension, delegate and others that I still miss sometimes in Python (perhaps because I still have to understand the mechanism deeply).