Python Forum
[PyQt] Setting icon on QAction from outside QGuiApplication
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyQt] Setting icon on QAction from outside QGuiApplication
#1
Exclamation 
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:
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_set
So 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).
Reply
#2
Try creating an instance of QApplication before creating an instance of JHActionSet
Reply
#3
QApplication() creates a QApplication object, and it sets up your application to run Qt. If you try to create a QAction object before calling QApplication(), you don't have the application framework required to manage the QAction object. The same thing happened when you tried to make a QIcon
Reply
#4
(Jan-02-2023, 06:56 PM)deanhystad Wrote: QApplication() creates a QApplication object, and it sets up your application to run Qt. If you try to create a QAction object before calling QApplication(), you don't have the application framework required to manage the QAction object. The same thing happened when you tried to make a QIcon

Thank you both, that seems to fix the problem and totally makes sense.
Hoper this doesn't have consequences in terms of efficiency.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyQt] QAction bold part of the string argument malonn 4 2,309 Sep-12-2022, 05:00 PM
Last Post: malonn
  PyQt6 QAction with icon and string malonn 2 1,720 Sep-12-2022, 11:59 AM
Last Post: malonn
  how to remove icon ilyess68ysl 4 3,734 Oct-15-2021, 10:05 AM
Last Post: ilyess68ysl
  Icon in tkinter menator01 8 5,013 May-03-2020, 02:01 PM
Last Post: wuf
  [Tkinter] Password Reveal Icon Evil_Patrick 2 4,690 Nov-29-2019, 02:20 PM
Last Post: Evil_Patrick
  [Tkinter] Window Icon Evil_Patrick 6 8,111 Oct-18-2019, 11:26 AM
Last Post: Evil_Patrick
  Button with Image Icon Friend 2 6,852 Jul-25-2019, 09:39 AM
Last Post: Friend
  [PyQt] Hide Dock Icon for QSystemTrayIcon App AeglosGreeenleaf 0 3,323 Jun-20-2019, 07:21 PM
Last Post: AeglosGreeenleaf
  [PyQt] How is this tray icon throbber done? JackDinn 7 4,838 Mar-05-2018, 02:19 PM
Last Post: JackDinn

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020