Icons from Resources not showing up in QPushButton or QToolButton
-
What's your path/prefix in your qrc file? See https://doc.qt.io/qt-5/resources.html
-
@Christian-Ehrlicher said in Icons from Resources not showing up in QPushButton or QToolButton:
What's your path/prefix in your qrc file? See https://doc.qt.io/qt-5/resources.html
As shown in the tree, the location is
./Resources/icons.qrc
As noted, the prefix is:
/icons
The few lines in the documentation doesn't bring me any new insight, I followed this logic, as well as I followed another logic with copying the path and as well as I tried couple of other things as shown. It probably something very simple I'm not doing right...
-
Hi,
Did you run pyrcc to generate the appropriate related code ?
-
@SGaist said in Icons from Resources not showing up in QPushButton or QToolButton:
Hi,
Did you run pyrcc to generate the appropriate related code ?
Nope, I did not run pyrcc, thank you for bringing this up, it's first time I hear of it. Neither the documentaion linked above or other tutorials mentioned it. From what I googled now it's a resource compiler and I would asume it would run together or before hand of the standard compiler.
Having said that, I do remember that one video tutorial mentioned, that first time after resources are set up, one have to run the project in a different way to get resources working (so not using the the green Play button, but from the menu). However I can't find anythig in the menu that would make sense (like CTRL+SHIFT+B - Compile All, that is greyed out).
An advice how to compile it from within QtCreator, or a link to tutorial or a dedicated documentation would be very appreciated.
-
The porting guide tutorial chapter 3 talks about rcc. Note that the name of the tool is pyside2-rcc for PySide2.
-
Heya,
I usually put this snippet in my resources location to update my resource file when im changing it alot:import subprocess from pathlib import Path file_path = Path(__file__) output_file = file_path.parent.parent / Path('guiResources.py') resource_file = file_path.parent / Path('resources.qrc') # cmd and sub process to generated new font resource file cmd = f'pyside2-rcc {resource_file} -o {output_file}' subprocess.call(cmd, shell=True)
my resource file will look something like this:
<RCC> <qresource> <file alias="sub_task_checked_16">icons/sub_task_checked_16.png</file> <file alias="progress_bar_1">icons/progress_bar/progress_bar_1.png</file> </qresource> <qresource prefix="font"> <file alias="Bebas">fonts/Bebas-Regular.ttf</file> </qresource> </qresource> </RCC>
this in my py file i call access an image with:
QtGui.QPixmap(':/sub_task_checked_16')
-
@SGaist Oh, I see the trick. Good to know. I think there's also another similar way - to set a "step" in the project settings in the execution of the program and define the comand there (so that it is executed before the python code itself).
I converted the icons.qrc file using pyside2-rcc and it went all right, with no messages, producing icons.py, which sits in the root of the project now. It's content looks jason-like (probably should).
I then imported the file in my header:
import icons
However, there's no change, I get no icons.
I deleted the both the icons.py and icons.qrc and created a new resource file iconsres.qrc with all the icons from scratch (using QtCrator GUI), this time in the root (not in the Resource folder). It should have no effect, because the icons.py was in the root anyway. I converted it to iconsres.py and changed the import line to
import iconsres
The icons are left like:
self.MainToolBar.addWidget(QPushButton(QIcon(':/icons/AddRecord.png'),'NNN')) self.MainToolBar.addWidget(QPushButton(QIcon(':/icons/gear.png'),'OOO')) self.MainToolBar.addWidget(QPushButton(QIcon(':/person.png'),'PPP')) self.MainToolBar.addWidget(QPushButton(QIcon(':/tools.png'),'RRR')) mbtnTestQ = QPushButton() mbtnTestQ.setText("Qqqqq") mbtnTestQ.setIconSize(QSize(24,24)) mbtnTestQ.setIcon(QIcon(QPixmap(":/icons/co.png"))) self.MainToolBar.addWidget(mbtnTestQ)
No change whatsoever :-(.
-
@alom Thank you for you suggestion. I tried omitting extension, it didn't work.
My resource file looks exactly like that, except that prefix is starting with a slash and whole content is enclosed in <RCC> tag. I tried to recreate the resource from scratch and omit the slash in prefix, which I left there the first time, but it has no effect - the slash is added automatically.
<RCC> <qresource prefix="/icons"> <file>Resources/AddRecord.png</file> <file>Resources/admin.png</file> <file>Resources/envelope.png</file> <file>Resources/gear.png</file> <file>Resources/helpLarge.png</file> <file>Resources/itemRev.png</file> <file>Resources/person.png</file> <file>Resources/plan.png</file> <file>Resources/Table_gray.png</file> <file>Resources/Table_green.png</file> <file>Resources/Table.png</file> <file>Resources/TableEdit.png</file> <file>Resources/TableEditCancel.png</file> <file>Resources/tagBlue.png</file> <file>Resources/tagGreen.png</file> <file>Resources/tagRed.png</file> <file>Resources/tools.png</file> </qresource> </RCC>
The converted file (iconsres.py) starts like this:
from PySide2 import QtCore qt_resource_data = b"\ \x00\x00\x01\x8f\ \x89\ PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\....................." ... ... ... def qInitResources(): QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) def qCleanupResources(): QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) qInitResources()
I even tried to add an extra new toolbar elsewhere, but id didn't help:
# Create pyqt toolbar toolBar2 = QToolBar() self.Lout = self.window.findChild(QLayout, 'HomeLayout') self.Lout.addWidget(toolBar2) # Add buttons to toolbar toolButton1 = QToolButton() toolButton1.setText("Apple") toolButton1.setIcon(QIcon(QPixmap(":/icons/plan.png"))) toolButton1.setCheckable(True) toolButton1.setAutoExclusive(True) toolBar2.addWidget(toolButton1) toolButton2 = QToolButton() toolButton2.setText("Orange") toolButton2.setIcon(QIcon(QPixmap(":/icons/tools.png"))) toolButton2.setCheckable(True) toolButton2.setAutoExclusive(True) toolBar2.addWidget(toolButton2)
The "Apple" and "Orange" are the new buttons of a new toolBar2. Can it be something with the size of the buttons? Setting icon size explicitly doesn't help:
toolBar2.iconSize = QSize(24, 24)
Setting toolbar height doesn't seem to have visual effect:
toolBar2.height = 60
Just to be sure, I'll create a new project and set everything from scratch, but if anyone has any ideas, I'd appreciate them.
-
-
Heya,
Hmmm... strange, i'm not sure where the issues is. If you not using an alias and only prefix, I would have though the file path should be:":/icons/Resources/TableEdit.png"
Thats why I use prefix and alias in my qrc file, so my path is always:
":/prefix/alias"
and if you just explicitly set the image path for a test, your the image is defiantly working fine?
toolButton1.setIcon(QIcon(QPixmap("your/local/network/path/plan.png")))
-
@alom Well, I would distinguish the file path in the XML file and resource reference in the code. When the inconsres.qrc is compiled into iconsres.py, it doesn't matter what paths are in the inconsres.qrc, as long as the iconsres.py contains the converted binary data (which in my case it appears it does, it looks similar to images when encoded to jason).
So then it's important that the reference from the code is correct to the encoded images. Something might be broken within the encoded iconsres.py file, the reference in QPixMap might be incorrect or something in the GUI object might be set wrong.Is my line of thinking correct?
Also, do I understand it right, that there are no tools to track variables and objects through execution? I mean something functionally similar i.e. to VS, like mouse hovering over included iconsres.py to see, that it contains objects like "icons/person.png", etc.
-
To be honest i'm not sure, but trying to recreate your example above in a test file at home, where I did not not use an aslias, I had to use
":/icons/Resources/TableEdit.png"
to get the image to show. Not including 'Resources" in the path failed to load it.
Unfortunately this is the extent of my knowledge with resource files
-
Heya,
yes I used the snippet I posted in my above post. I save this as a separate .py file where i keep my resources and run this to generate my files. You need to make sure your system path env has acess to pyside2-rcc, else you need to modify the code to point to the pyside2-rcc on your network.import subprocess from pathlib import Path file_path = Path(__file__) output_file = file_path.parent.parent / Path('guiResources.py') resource_file = file_path.parent / Path('resources.qrc') # cmd and sub process to generated new font resource file cmd = f'pyside2-rcc {resource_file} -o {output_file}' subprocess.call(cmd, shell=True)
-
@alom I still can't make it work. Your way is exactly how I do it, but for the moment I run the command directly as noted above.
I did another test with QLabel:
The imgs.qrc is shown in the screenshot including it's content, one picture (qtlogo.png). Converted this way:
pyside2-rcc imgs.qrc -o imgs.py
Code fractions:
from PySide2.QtWidgets import ..., QToolButton, ..., QLabel from PySide2.QtGui import QIcon, QPixmap import imgs ... self.pic1box = self.window.findChild(QLabel, "Pic1") self.pic1box.setText = "/home/../Test8/qtlogo.png" self.pic1box.setPixmap(QPixmap("/home/libor/Coding/Projects/Test8/qtlogo.png")) self.pic2box = self.window.findChild(QLabel, "Pic2") self.pic2box.setText = ":/img/qtlogo.png" self.pic2box.setPixmap(QPixmap(":/img/qtlogo.png")) self.pic3box = self.window.findChild(QLabel, "Pic3") self.pic3box.setText = ":/qtlogo.png" self.pic3box.setPixmap(QPixmap(":/qtlogo.png")) self.pic4box = self.window.findChild(QLabel, "Pic4") self.pic4box.setText = ":/img/qtlogo" self.pic4box.setPixmap(QPixmap(":/img/qtlogo")) self.pic5box = self.window.findChild(QLabel, "Pic5") self.pic5box.setText = ":/qtlogo" self.pic5box.setPixmap(QPixmap(":/qtlogo")) self.pic6box = self.window.findChild(QLabel, "Pic6") self.pic6box.setText = ":/Resources/img/qtlogo.png" self.pic6box.setPixmap(QPixmap(":/qtlogo.png"))
All icons and images shown have the path set directly, not via resource file.
-
What version of PySide2 are you using ?
-
@SGaist I don't know if this is a proper way to find out, but versions are listed:
> pip install --upgrade PySide2 Defaulting to user installation because normal site-packages is not writeable Requirement already up-to-date: PySide2 in /usr/lib64/python3.6/site-packages (5.15.0a1.dev1584103015) Requirement already satisfied, skipping upgrade: shiboken2==5.15.0a1.dev1584103015 in /usr/lib64/python3.6/site-packages (from PySide2) (5.15.0a1.dev1584103015)
-
OK, there are example apps that come with PySide2. Now I went into this one, which is using resource file:
/usr/lib64/python3.6/site-packages/PySide2/examples/widgets/animation/appchooser/
...and run it:
> python3 ./appchooser.py QPixmap::scaled: Pixmap is a null pixmap QPixmap::scaled: Pixmap is a null pixmap QPixmap::scaled: Pixmap is a null pixmap QPixmap::scaled: Pixmap is a null pixmap QPixmap::scaled: Pixmap is a null pixmap QPixmap::scaled: Pixmap is a null pixmap QPixmap::scaled: Pixmap is a null pixmap QPixmap::scaled: Pixmap is a null pixmap
and I see only white blank window. Could someone try to run this example app and let me know it it is working? I wonder, if it's connected to this issue I'm experiencing with resource files.