Using relative path for image:url in stylesheet
-
Hi,
If you want to simplify things, you should consider using the Qt resources system so the icons are embedded in your executable and not dependent on the binary location.
-
Hi,
You should implement @SGaist's suggestion, it's way more efficient.
But if you insist on your current approach, you just need to realize that the path is relative to your program's executable location, which you can find in your build folder (build-simpleclient-Desktop...), not your source folder (simpleclient).
So you could either copy your icons into your build folder.
Or you could use the icons where they currently are without changing there location like this:
image: url(../icons/green_circle.png);
../
means parent folder.For more clarification, here's the equivalent to your relative paths:
image: url(C:/Users/petrikas.lu/Desktop/WORK/QT/PTL/simpleclient/build-simpleclient-Desktop_Qt.../icons/green_circle.png);
Which is wrong because such file does not exist, hence why it doesn't work.
Again, I advice you to implement @SGaist's suggestion.
Hope this helps!
-
@Abderrahmene_Rayene said in Using relative path for image:url in stylesheet:
Or you could use the icons where they currently are without changing there location like this:
image: url(../icons/green_circle.png);
../
means parent folder."Parent folder" from where is it interpreted as?? If it's parent from runtime working directory it's quite useless....
-
@Abderrahmene_Rayene
Not sure how to phrase it any clearer. You talk about using a relative path forurl(...)
argument, yours starts with../
. Which does indeed mean "parent directory". But I am asking you: parent directory from where?? Parent of which directory?Do you mean parent from "the current working directory at runtime of the program"? If so, since you have no idea what that might be when running the program I don't see how it helps or how I could ever use it for production. It might be useful if you are developing in Creator and cause that to set your runtime working directory to somewhere known when spawning your executable, but outside of that I cannot see that it helps. If it meant, say, "relative to the directory in which the executable is located" then it would be useful, but I don't think Qt treats it that way.
-
@JonB said in Using relative path for image:url in stylesheet:
relative to the directory in which the executable is located
Yes that is what I meant, my post is based on OP's current folder hierarchy, their build folder is in their working directory.
I know this is not production level, but OP seems to not understand how this works, like I was just 2 months ago, so I'm just providing an explanation based on their current situation, not a general one.
The screenshot they shared shows their current hierarchy which I based my explanation to OP's specific situation on. I just thought they shouldn't move on from this without actually understanding what they did wrong.
-
Thanks for the help. I have ended up using the QT resource system as you guys suggsted. I refer to this documentation:
https://doc.qt.io/qt-5/resources.htmland found this Youtube video to be very easy to follow and got it to work quite fast.
https://www.youtube.com/watch?v=b2urUjl03EY&ab_channel=MacDigia -
@Abderrahmene_Rayene
I understand you are trying to help the OP, and my comment is not intended to "criticise" you. But you sayyou just need to realize that the path is relative to your program's executable location
Although I have not tested, I think this incorrect. Unless you show otherwise or have a reference for that for a Qt
url()
, I see no evidence it takes the location of the executable into account at all. Rather I believe it is relative to the *runtime current directory", which could be anywhere at all, not related to the executable's location. Which means using a relative path is pretty useless to locate any existing file to read, and consequently we recommend people not to use a relative path. When building and running from Creator, that may set the program's current directory to the "build" folder where the executable is located, but that is just a Creator thing, and won't apply outside. Hence @SGaist's suggestion of using Qt's resources, whose paths always work.If the user tries from a terminal:
cd /tmp /path/to/build/folder/executable-file
does it then find the original
../icons/green_circle.png
, or does it say it does not exist because it looks for/icons/green_circle.png
? -
@Abderrahmene_Rayene
@JonB
@SGaistThis is a little out of topic but its relevant.
What is the best way to display an icon without any additional widgets.
I have noticed that not all widgets support setIcon method.
For example , for my particular application, I now have the following:
void MainWindow::on_pushButton_clicked() { if(ui->status_checkbox_test->checkState() == Qt::Unchecked){ ui->status_checkbox_test->setCheckState(Qt::Checked); ui->status_checkbox_test->setIcon(QIcon(":/icons/green_circle.png")); return; } else if(ui->status_checkbox_test->checkState() == Qt::Checked){ ui->status_checkbox_test->setCheckState(Qt::Unchecked); ui->status_checkbox_test->setIcon(QIcon(":/icons/red_circle.png")); return; } }
Checkbox toggled:
Checkbox not toggled:
My issue
Since I am using QCheckBox, even after setting the icon using
setIcon
I am seeing the checkbox text and the actual checkbox. However, in my case I would only like to display icon without anything else. Is there a widget in QT that is dedicated just for icon?Simply said:
What if I want to simply insert an icon somewhere on the screen. What widget would I choose since I need a widget to use
setIcon
property? -
@lukutis222 said in Using relative path for image:url in stylesheet:
What if I want to simply insert an icon somewhere on the screen. What widget would I choose since I need a widget to use setIcon property?
QLabel
has setPixmap(const QPixmap &), which accepts more thansetIcon()
would, but can take icons too. -
@JonB
Sure, I can use QPixmap to dispaly an icon:
This method uses QLabel to replace with icon:
QPixmap* pixmap =new QPixmap (":/icons/green_circle.png"); ui->test_label->setPixmap(*pixmap); ui->test_label->setScaledContents(true);
Is this a common way to do this in QT? If I just want to display an Icon, I would create a label widget and just replace it icon?
Additionally, My image does not actually seem to have transparent background even though when I open it using image editor it shows as transparent.
I have set QLabel background color to test it out:
The result:
I would have expected to see green circle in yellow background
-
@lukutis222 said in Using relative path for image:url in stylesheet:
QPixmap* pixmap =new QPixmap (":/icons/green_circle.png");
ui->test_label->setPixmap(*pixmap);
ui->test_label->setScaledContents(true);Don't create the QPixmap on the heap, there's no need for that.
As for your other question, QLabel is a class made to show text or images so yes, it's pretty common to use it to show images like that. You could also implement your own subclass that paints the image but there would not be much benefit from that.
-
@lukutis222 said in Using relative path for image:url in stylesheet:
I would have expected to see green circle in yellow background
Does your
green_circle.png
have transparent background? -
@JonB said in Using relative path for image:url in stylesheet:
my comment is not intended to "criticise" you.
I appreciate any feedback I can get, thank you!
I can see your point, which made me doubt my past experiments and understandings, as I'm still at the beginning of my learning journey.
So I made a little experiment. I created a new project with a check box, used OP's styelsheet, with my suggested relative path:
image: url(../icons/green_circle.png);
I then made a whole new directory separated from the project folder, and created a folder called
executableFolder
, and one calledicons
. When I run the executable (copied from the build directory), the stylesheet works.Here are the directories:
user@user:~/Desktop/UnrelatedDir$ ls executableFolder icons user@user:~/Desktop/UnrelatedDir$ cd executableFolder/ user@user:~/Desktop/UnrelatedDir/executableFolder$ ls relativePath user@user:~/Desktop/UnrelatedDir/executableFolder$ cd ../ user@user:~/Desktop/UnrelatedDir$ cd icons/ user@user:~/Desktop/UnrelatedDir/icons$ ls green_circle.png red_circle.png
relativePath
is the executable.Also, I made sure those images exist nowhere but in icons folder in the
UnrelatedDir
directory.Is this the correct experiment to demonstrate how relative paths work? If not, what should I change or try, in order to properly understand how it works? And is there something I should be aware of, that I seem to be ignorant about?
-
@Abderrahmene_Rayene said in Using relative path for image:url in stylesheet:
Is this the correct experiment to demonstrate how relative paths work?
No! This demonstrates what you already have/know from Creator. Because of your
cd executableFolder/
you are precisely making sure the current directory HAPPENS to be where the executable lives. This is also how Creator runs your app. So../icons/green_circle.png
is correct just for this case.But you don't know where the user might be when they run your app. All you have to do to test is what I wrote above:
cd /tmp ~/Desktop/UnrelatedDir/executableFolder/relativePath
Now does it still pick up the
green_circle.png
? -
@JonB No it does not, and I get it now.
In my case I made the executable's directory the working directory by navigating towards it and executing it by clicking on it in a file manager.
To demonstrate that I understood, I copied the icons folder into
tmp
, and ran your command again, and it foundgreen_circle.png
.I think I understand now, Thank you!
-
@Abderrahmene_Rayene said in Using relative path for image:url in stylesheet:
by navigating towards it and executing it by clicking on it in a file manager
Indeed, but that probably depends on your File Manager/OS. And after a while you/the user may set up a "shortcut" icon for the executable on the desktop and double-click that. Now what is the current directory when it is launched? Each OS/File Manager has its own settings or rules.
So how can we locate supplied external files? One possibility that suits your case is to use QString QCoreApplication::applicationDirPath() to find where the executable is. If you installed the
icons
directory there or thereabouts you might appendicons/
or../icons/
to that path to locate the.png
. That is OK from code, but you can't pass anything suitable to the original stylesheet'surl(...)
for this case. You mightcd
there from within your application's code, so that relative works like it does from Creator, but that has consequences, plus it can breakQCoreApplication::applicationDirPath()
.... [Oh, and also it won't for Qt Python applications.]The upshot is, especially for this
url(...)
syntax, you are probably best off switching to Qt's resources to supply your icons instead of as external files, as @SGaist suggested and @lukutis222 has now adopted.P.S.
What would really be better is if Qt "QSS" stylesheets either defined whereurl(...)
sought relative paths somehow relative to where the executable is or some environment variable specifies, or added an extra syntax inurl(...)
to refer to the executable directory. If we were in HTML with CSS sheets, I believe relative paths are from where the page being viewed is located, and/or an absolute URL/...
refers to the virtual root directory of the application, so one can work with that. -
@lukutis222 Could you share
green_circle.png
file? and the style sheet you're applying to your label?I tested with a random green circle icon with a transparent background, and a yellow background for the label, and it works.
Here's how it looks:
and here's the image I used, and its link: