Solved Qt Style Sheets cascading classes selectors
-
@JNBarchan hi, actually you can asign specific class names. For example:
QPushButton#btnBack{border-image:url(:/data/NavIcons/btnPrev.png);}
sets the stylesheet to all QPushButtons with the objectname
btnBack
you can also combine that with other default states
or custom states(Q_Properties) as in this example:QPushButton#btnUnits[state = true]:pressed{border-image:url(:/data/NavIcons/Menu_Imp.png);} QPushButton#btnUnits:pressed{border-image:url(:/data/NavIcons/Menu_Si.png);}
taken from my current project.
-
[Forget about "state selectors, like
:pressed
, they are not at issue.]Thanks, but I'm afraid that does not solve the problem.
#
id is available in HTML/CSS. But it does not allow for multiple classes (let alone that it relies on widget having a particular object name"), which is what I need.In HTML/CSS I can have multiple elements on same or multiple pages like:
<span class="green bold tall sunken"></span> <span class="red bold tall outset"></span> <span class="bold short outset"></span> ...
So I can build up each CSS class definition (of what
bold
,short
, etc. are) separately and combine them at will. This is what we do in HTML/CSS, and I am stumped as to how to achieve it in Qt across "50 pages with 20 widgets each".I would need Qt to offer some equivalent of:
label1 = QLabel() label1.classes = "green bold tall sunken" label2 = QLabel() label2.classes = "red bold tall outset"
Do you follow why? And if Qt does not offer this, it will be almost impossible to achieve a maintainable set of QCSS definitions, which would be an awful shame.... :(
-
@JNBarchan mmh, I'm afraid, I'm not that involved/knowledgable with StyleSheets to give you a defenite Yes or No answer on this one.
Maybe someone else can give you a better answer.Would comes to my mind right now, is, you could create multiple QSS-files that you add to your ressource file and load a specific one from inside your classes.
-
@J.Hilk
Thanks for your attempt. I need a Qt stylesheet expert then... :) -
@JNBarchan I use CSS heavily in my
QWidget
application and unfortunately I've also not come across a way to achieve this.What I've done in my application is to use a "dynamic property" called
class
and against this, I specify a CSS class which then links through to my stylesheet.For example, in the designer I have a
QPushButton
with aclass
ofred
, my stylesheet then contains:QPushButton[class="red"] { background-color: red; }
I know it isn't what you are looking for but given that
QWidgets
do not explicitly allow CSS classes to be bound to them (or chained), I think your best bet is to look for other options. -
Hold the phone!!
Ignore my answer.
Assign a dynamic property called "class" and in this, specify your class names (can be many), for example "red blue". Now, in your stylesheet if you have:
.red { color: red; } .blue { background-color: blue; }
You will get a
QPushButton
with red text and blue background! It works -
@webzoid
Oooohhh, I have held the phone, and this looks perfect!I am new to Qt, and I'm afraid I use Python/PyQt (and no Qt Creator). How (C++ will do) do I do:
Assign a dynamic property called "class"
?
-
@webzoid wait wait, could you elaborate that example a bit for all us none StyleSheet Experts x)
-
@JNBarchan I believe the
QObject::setProperty
function is how you would assign a dynamic property in c++. See herehttp://doc.qt.io/qt-5/qobject.html#setProperty
@J-Hilk I will post my worked example for download shortly...
-
Here's a
QWidgets
example:https://drive.google.com/open?id=1XbOJgF6DNqsmq_JR5c9gfWiHv3poHPWV
The "style.css" file needs to live alongside the executable in order for this to work. Or change the code...
-
@webzoid said in Qt Style Sheets cascading classes selectors:
@JNBarchan I believe the
QObject::setProperty
function is how you would assign a dynamic property in c++. See hereHopefully, you are a hero(!), though not time to try it right now.
From the docs I note:
If the property is defined in the class using
Q_PROPERTY
then true is returned on success and false otherwise. If the property is not defined usingQ_PROPERTY
, and therefore not listed in the meta-object, it is added as a dynamic property and false is returned.Being Python/PyQt, I don't know how (or even if it's possible) to do
Q_PROPERTY
. Assuming I can't, does yourclass
property principle work OK if that is absent? -
@JNBarchan Unfortunately I'm coming from the Windows
QWidget
application side of things so I really can't comment on what Python/PyQt will do in this instance.I have just done a test whereby I call the
setProperty
function from C++ as follows:ui->pushButton->setProperty("class", "red thick-border");
and the result is exactly the same as if I'd done it in the designer. Hopefully PyQt works in the same way.
-
@JNBarchan Q_Property is part of QObject that is the essential part of what makes qt qt, so I would be seriously surpised if its not possible.
@webzoid thank you very much! That will help a lot of people for a long time ;-)
-
@J.Hilk It's definitely helped me already!
-
@JNBarchan Unfortunately I'm coming from the Windows QWidget application side of things so I really can't comment on what Python/PyQt will do in this instance.
No, we're on the same page there. I inherit from
QWidget
OK just like you do. But (I believe) you can do something like:class MyWidget : QWidget { Q_PROPERTY QString cssClass; // declare cssClass member as a known property in MyWidget ... this.cssClass = "red blue"; }
I can't (don't know how to/if I can) use that
Q_PROPERTY
macro you have, so just:class MyWidget(QWidget) { ... self.cssClass = "red blue"; }
But I think you are not using
Q_PROPERTY
anywhere yourself, you just goui->pushButton->setProperty("class", "red thick-border");
, so yourclass
is:therefore not listed in the meta-object, it is added as a dynamic property
Is that correct for your C++ situation? Which is all I can do, and looks same as what you are doing to me, so I should be OK?
-
@J.Hilk said in Qt Style Sheets cascading classes selectors:
@JNBarchan Q_Property is part of QObject that is the essential part of what makes qt qt, so I would be seriously surpised if its not possible.
? a. I think it's a macro, so what is its expansion anyway? and b. in Python we do not even declare any member variables in a class (not my fault, I didn't choose Python), so ... ?
-
@JNBarchan said in Qt Style Sheets cascading classes selectors:
@J.Hilk said in Qt Style Sheets cascading classes selectors:
@JNBarchan Q_Property is part of QObject that is the essential part of what makes qt qt, so I would be seriously surpised if its not possible.
? a. I think it's a macro, so what is its expansion anyway? and b. in Python we do not even declare any member variables in a class (not my fault, I didn't choose Python), so ... ?
Well, yes, technically its a Macro (I think), I found this webside
Support for Qt Properties for PyQt5
seems like a good place to start, I guess.
-
@J.Hilk
actually this is already stated in the docs.
Altough i am surprised that it works when you assign a string with space-separated values instead of a QVariant containing a QStringList. -
@raven-worx
Thanks, I needed that link. I had not come across it, its discussion ofsetProperty()
, dynamic properties, multiple properties, use of~=
, etc. Obscure (for me)!I see it says:
In addition, the special
class
property is supported, for the name of the class.This might explain why my attempts so far to set & match my own property named
class
, as per @webzoid's suggestion, has not been working...! -
@raven-worx
I'm really struggling here, because what should be working just isn't. I'm not even as far as multiple property/space-separated strings, just one item:-
I create a
QLabel
. -
Stylesheet: (global, nothing else in it)
QLabel { color: red; }
-
Change to:
QLabel[cssClass="red"] { color: red; }
, or toQLabel[cssClass~="red"] { color: red; }
-
Change code to:
label.setProperty("cssClass", "red")
After #2 it's red. After #4 it ceases to be red :(
I know it's Python/PyQt --- and I can't test C++ or QML --- but I really think the
setProperty()
will be a straight, pass-through call.Would someone be prepared to just try as simple as above?
-