When I was doing this tutorial: Using the PyQt5 ModelView Architecture to build a simple Todo app
I realized the icons would not display unless I had them downloaded to my machine. Did you get the calendar icon and cross icon from the Fugue set where you got the others?
Are there any built-in icons with PyQt5? I have searched the web and it seems like there are some but I can’t find any examples of them being used in this way. Does it depend on the situation? If so, then in which cases can I use an icon without downloading it first?
Thank you for your help.
Yep, that’s right – the icon there is from the same fugue icons set.
The answer re: built-in icons is a bit longer, as there are two things that this can mean – either Qt built-in, or system built-in (Linux only). I’ll start with the Qt built-ins as that’s cross-platform.
Qt Standard Icons
Qt ships with a small set of standard icons you can use in any of your applications for common actions. The icons are all accessible through the current active application style using .standardIcon(name)
.
There is a nice little script here which displays them all in a window for you, along with their names.
The full table is below –
… | … | … |
---|---|---|
SP_ArrowBack | SP_DirIcon | SP_MediaSkipBackward |
SP_ArrowDown | SP_DirLinkIcon | SP_MediaSkipForward |
SP_ArrowForward | SP_DirOpenIcon | SP_MediaStop |
SP_ArrowLeft | SP_DockWidgetCloseButton | SP_MediaVolume |
SP_ArrowRight | SP_DriveCDIcon | SP_MediaVolumeMuted |
SP_ArrowUp | SP_DriveDVDIcon | SP_MessageBoxCritical |
SP_BrowserReload | SP_DriveFDIcon | SP_MessageBoxInformation |
SP_BrowserStop | SP_DriveHDIcon | SP_MessageBoxQuestion |
SP_CommandLink | SP_DriveNetIcon | SP_MessageBoxWarning |
SP_ComputerIcon | SP_FileDialogBack | SP_TitleBarCloseButton |
SP_CustomBase | SP_FileDialogContentsView | SP_TitleBarContextHelpButton |
SP_DesktopIcon | SP_FileDialogDetailedView | SP_TitleBarMaxButton |
SP_DialogApplyButton | SP_FileDialogEnd | SP_TitleBarMenuButton |
SP_DialogCancelButton | SP_FileDialogInfoView | SP_TitleBarMinButton |
SP_DialogCloseButton | SP_FileDialogListView | SP_TitleBarNormalButton |
SP_DialogDiscardButton | SP_FileDialogNewFolder | SP_TitleBarShadeButton |
SP_DialogHelpButton | SP_FileDialogStart | SP_TitleBarUnshadeButton |
SP_DialogNoButton | SP_FileDialogToParent | SP_ToolBarHorizontalExtensionButton |
SP_DialogOkButton | SP_FileIcon | SP_ToolBarVerticalExtensionButton |
SP_DialogResetButton | SP_FileLinkIcon | SP_TrashIcon |
SP_DialogSaveButton | SP_MediaPause | SP_VistaShield |
SP_DialogYesButton | SP_MediaPlay | |
SP_DirClosedIcon | SP_MediaSeekBackward | |
SP_DirHomeIcon | SP_MediaSeekForward |
The code to get the icon here is a little packed into one line, so I’ve split it out below to make it easier to follow.
name = 'SP_MessageBoxCritical'
style = <widget>.style() # Get the QStyle object from the widget, e.g. usually `self`
icon = style.standardIcon(name)
.setIcon(icon)
Free Desktop Icons
On Linux desktops there is a thing called the Free Desktop Specification which defines standard names for icons for specific actions.
If your application uses these specific icon names (and loads the icon from a “theme”) then on Linux your application will use the current icon set which is enabled on the desktop. The idea is making all application have the same look & feel while remaining configurable.
To use these within Qt Designer you would select the drop-down and choose “Set Icon From Theme…”
You then enter the name of the icon you want to use, e.g. document-new
(the full list of valid names).
If you’re not using designer, you can set icons from a theme using the following.
icon = QtGui.QIcon.fromTheme("document-new")
self.pushButton_n6.setIcon(icon)
However, if you’re developing a cross-platform application you’ll still need your own icons for Windows & MacOS.
Than you for the reply, and for the link. If I understand correctly, this means that in the particular case of conditional formatting we DO need to download the icons first. I tried to see if I could do so with the code from the tutorial but it doesn’t look possible. Is that correct? If not, then could you please show how it would be applied for conditional formatting in a table?
Also, does the .fromTheme() option only work on Linux?
If I understand correctly, this means that in the particular case of conditional formatting we DO need to download the icons first.
For the calendar icon yes, as there isn’t a built in calendar icon. But we could use one of the cross icons from the built in set if we wanted, e.g. something like (untested)
# ticks and crosses for `bool`values
def data(self, index, role):
if role == Qt.DecorationRole:
value = self._data[index.row()][index.column()]
style = self.style()
if isinstance(value, bool):
if value:
return QtGui.QIcon(style.standardIcon('SP_DialogApplyButton'))
return QtGui.QIcon(style.standardIcon('SP_DialogCancelButton'))
…though using dialog apply/cancel icons for this isn’t particularly “nice” and you should aim for a consistent UI style by using a single icon theme throughout.
Also, does the .fromTheme() option only work on Linux?
Qt themes work on all platforms, it’s just that on Linux you get the theme for “free”. On non-Linux platforms you have to define your own icon theme from scratch. The benefits of doings this are limited, though a tutorial on it is planned. It’s only really worth doing if you want to have a Linux-native look on Linux desktops. For other use cases the QResource
system is simpler.
Thank you for the reply. I tried this yesterday and it did not work. I tried it again after you posted it, to double check, and I get the same error: ‘TableModel’ object has no attribute ‘style.’
Instead I found that this worked:
First, at the top I imported the following:
#additional import to access built in icons
from PyQt5.QtWidgets import QApplication, QStyle
Second, I changed the relevant portion of the data method:
if role == Qt.DecorationRole:
value = self._data[index.row()][index.column()]
style = QApplication.style()
if isinstance(value, bool):
if value:
return QtGui.QIcon(style.standardIcon(QStyle.SP_DialogApplyButton))
return QtGui.QIcon(style.standardIcon(QStyle.SP_DialogCancelButton))
Is this a good solution? Would this solution apply in similar situations? Which objects do or do not have style attributes?
Thank you for your help.
Yep, that’s a good solution – my mistake was forgetting that the
data
method was on a subclass of a model and not QWidget
. Any subclass of QWidget
will have the style method to get the active style applied to that widget. It doesn’t matter what style object you use as we’re just using it for the builtins.
But it’s nicer as you’ve done to use the enum to access QStyle.SP_DialogApplyButton
than the string lookup.
If you are making a application for Windows or Macos and that you want a set of icons, you should take a look at Pling ex opendesktop.org.
Here you can get icons or pack theme icons and they are obviously open-source and free. But think to respect the licence.
I have not think to check if Qt had some icons pre-installed. Nice explanation about this subject.
Thank you, @Eolinwen! This is an awesome collection, and it’s great to have the theme icons as well.
It is with a great pleasure if I can help.
In fact, it depends on which system you are designing your app and personally even I’m an old Linux user, I prefer to use my own icons.
This was a really helpful script as I was recently making a custom theme for my app. Thank you!