Qt Style Sheets cascading classes selectors
-
@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.
-
@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 -
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 -
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 -
@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...
-
@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...
@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? -
@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.
-
@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 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 ;-)
-
@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 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?
-
@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 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 ... ?
-
@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.
-
@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. -
@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...! -
@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
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?
-
-
@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?
@JNBarchan
i never used PyQt in my life, so i have absolutely no experience with it.Do you mean you change the stylesheet at runtime? Or do you just want to specify the stylesheet once from application startup and never change it again?
In c++ i would do this:
QLabel* label = new QLabel; label->setProperty("cssClass", QVariant::fromValue<QStringList>( QStringList() << "red" ) );
and in the stylesheet:
QLabel[cssClass~="red"] { color: red; }
I don't what the equivalent of a QStringList in PyQt.
-
-
@JNBarchan
i never used PyQt in my life, so i have absolutely no experience with it.Do you mean you change the stylesheet at runtime? Or do you just want to specify the stylesheet once from application startup and never change it again?
In c++ i would do this:
QLabel* label = new QLabel; label->setProperty("cssClass", QVariant::fromValue<QStringList>( QStringList() << "red" ) );
and in the stylesheet:
QLabel[cssClass~="red"] { color: red; }
I don't what the equivalent of a QStringList in PyQt.
No, no need to change at runtime, all from startup.
I assume what you have written actually does work for you?
In Python (PyQt), we can't have
QString
, orQStringList
, orQVariant
:( (Don't ask, that's how it is...) PyQt's declaration ofsetProperty()
is that it acceptsAny
, which means you pass any type from the language....Please, keeping it simple, no lists, would yours still work if you wrote:
label->setProperty("cssClass", "red" );
Or, if that does not work, what about:
label->setProperty("cssClass", QVariant::fromValue<QString>( "red" ) );
(And we could stick to
=
not~=
in the stylesheet. I'm trying to do everything with just one item, no lists, to get anything working here...) -
No, no need to change at runtime, all from startup.
I assume what you have written actually does work for you?
In Python (PyQt), we can't have
QString
, orQStringList
, orQVariant
:( (Don't ask, that's how it is...) PyQt's declaration ofsetProperty()
is that it acceptsAny
, which means you pass any type from the language....Please, keeping it simple, no lists, would yours still work if you wrote:
label->setProperty("cssClass", "red" );
Or, if that does not work, what about:
label->setProperty("cssClass", QVariant::fromValue<QString>( "red" ) );
(And we could stick to
=
not~=
in the stylesheet. I'm trying to do everything with just one item, no lists, to get anything working here...)@JNBarchan said in Qt Style Sheets cascading classes selectors:
In Python (PyQt), we can't have QString, or QStringList, or QVariant :( (Don't ask, that's how it is...)
This questions everything else then, if it is even possible at all.
I have no idea then what exactly is assigned to the property in the background.Do you set the property before the widget is shown? Best would be to set the property right after instantiation.