QSS properties for custom widget: How to implement hover and pressed states - qt

I found this example on the web on how to implement custom properties accessible from QSS for custom QWidgets: https://qt-project.org/wiki/Qt_Style_Sheets_and_Custom_Painting_Example
Does anyone know how can I implement the widget so that I can have different colors for hover or pressed states?
Current stylesheet looks like this:
SWidget
{
qproperty-lineColor: yellow;
qproperty-rectColor: red;
}
I want to be able to have something like this:
SWidget:hover
{
qproperty-lineColor: blue;
qproperty-rectColor: green;
}
SWidget:pressed
{
qproperty-lineColor: orange;
qproperty-rectColor: violet;
}
Note: I know it is possible to implement mouse events and change the colors using qproperties specific to the mouse events, for example:
SWidget
{
qproperty-lineColor: yellow;
qproperty-rectColor: red;
qproperty-lineColor-hover: orange;
qproperty-rectColor-hover: violet;
}
but I would like to be able to make it work using the original qss/css way.
Regards!

When user hover or pressed widget, you should change some widget property. And make different QSS selector for that properties.
After change property you should make unpolish\polish of application styles.
qApp->style()->unpolish( this );
qApp->style()->polish( this );
Where "this" current window pointer. That "magic" code will help to have affect of appropriate QSS selector.

Related

Qt: Style depending on label value

I have what looks like a very simple problem: I want to design a QLabel whose value changes dynamically (no issue here) and whose background color changes accordingly (this is the issue).
Of course, I know I can do something like that (pseudo code):
function on_new_value(value):
label.setText(value)
if value>10:
label.setBackgroundColor(RED)
else if value<0:
label.setBackgroundColor(RED)
else:
label.setBackgroundColor(GREEN)
But that kind of mixes model and view. What I'd like, ideally, would be to be able to use an extended version of Qt Stylesheets as follows:
QLabel { background: green; }
QLabel { if value>10: background: red; }
QLabel { if value<0: background: red; }
Obviously, that is not possible. But I'm wondering if Qt allows for something close in order to embbed (for instance in a class) a graphic behaviour based on a value.
I know about QPalette, but the style condition is only about the widget Active/Disable state, not its "value".
In other words, I'm looking for sort of a ValueDependantStyle class or somehting close.
Any pointers? Am I looking at this all wrong?
Edit: in case this is important, I'm developping with PyQt5.
You could use a "model property" on the label, that defines the color in a style sheet (cf. Qt Style Sheet Reference about properties):
function on_new_value(value):
label.setText(value)
if value>10:
label.setProperty("HasError", "true")
else if value<0:
label.setProperty("HasError", "true")
else:
label.setProperty("HasError", "false")
QLabel[HasError="false"] { background: green; }
QLabel[HasError="true"] { background: red; }

ToolbarSearch not being customized in the UI

According to this blog post, it should be possible to style the ToolbarSearch by customizing the UIIDs ToolbarSearch,TextFieldSearch and `TextHintSearch.
In my CSS File it looks like this:
ToolbarSearch {
color: white;
height:30mm;
width:30mm;
}
TextHintSearch {
color: white;
height:30mm;
width:30mm;
}
TextFieldSearch {
color: white;
height:30mm;
width:30mm;
}
The main thing I want to achieve is a white Search Button, Text, X-Button and Hint.
In the blog post above, it looks right, except the textfieldsearch and -hint:
But in my application it looks like this:
The buttons are in the wrong color. What am I doing wrong?
Notice:
This is how I add it
this.getToolbar().addSearchCommand(e -> {
//TODO search
});
(The algorythm is not implemented yet)
I don't use the CSS plugin so I'm not really sure how this maps there but you need to override the selected/pressed & unselected styles.

LESS mixins vs classes

I'm looking into LESS because I definitely see some of their benefits. For instance colour declaration.
One thing I don't understand tho, and maybe I'm not getting the flow right is - why use the following LESS snippet
.radius {
-webkit-border-radius:5px;
-moz-border-radius:5px;
border-radius:5px;
}
.btn-red{
background-color:red;
.radius;
}
.btn-green{
background-color:green;
.radius;
}
...
When we can use the .radius class in the html file right away. I'm left with the impression that LESS will add a ton of duplicate code once it gets compiled.
I'm using the following, which makes more sense. Same with font-size, margins, etc... Aren't classes used in such cases?
<div class="btn-red radius">Cancel</div>
<div class="btn-green radius">Go</div>
The snippet above does not benefit from SASS/LESS capabilities that much. Lets have a closer look and check this SCSS snippet.
// Abstract placeholder.
%radius {
border-radius: 5px;
}
// Put your global styling here.
// I'm assuming that you can alter the markup and have button.btn.btn-green
.btn {
// Color modifier.
&-red {
#extend %radius;
background-color: red;
}
&-green {
#extend %radius;
background-color: green;
}
}
The CSS output will be:
.btn-red, .btn-green {
border-radius: 5px;
}
.btn-red {
background-color: red;
}
.btn-green {
background-color: green;
}
And then you have to pick up Autoprefixer and vendor-prefixes issue is solved once and for all.
Because now, you can just specify the class btn_red or btn_green and all the buttons will automatically have a radius.
Your HTML should contain only the semantics, and styling or classes referring to styling should not be part of it.
That applies to the other classes as well. If for instance, you would rename btn_red to btn_cancel, you have a meaningful classname that you can apply to any kind of cancel button. And in the CSS you can specify that a cancel button is red and a 'Go' button is green, and both have a radius, without needing to modify the HTML at all.
So, the ultimate goal is to have the HTML describe the structure and the CSS describe how that structure should look. And a CSS preprocessor is only their to make a bulky spaghetti-like CSS file more structured.
There are several benefits.
You can use more semantic class names. Rather than encoding style information directly in your class names, (btn-red, radius) you could use a single class that conveys the usage of the style, rather than its contents.
You can avoid repeating yourself.
#radius-size: 5px;
-webkit-border-radius:#radius-size;
-moz-border-radius:#radius-size;
border-radius:#radius-size;
You can parameterize it so that you'd be able to use different radiuses (radii?) in different contexts.
.radius(#radius-size) { ... }
Because there are cases that developer has-no-access or don't-want to change the markup. and the only solution is to include all props from a predefined class.
for example:
you have bootstrap loaded (then you already have .has-success and .has-error classes) and if you want to use HTML5's native form validation using input's :valid and :invalid states, you have to use JavaScript to add/remove success/error classes based on input's states. but with this feature of LESS you can include all props of success/error class inside input's states. the code for this example could be something like this:
#myinput {
&:valid { .has-success; }
&:invalid { .has-error; }
}

How to apply diffrent css style on different events of an asp button?

I have a web user control where I have ten asp buttons.
I want that when I hover on these buttons the cursor should change to hand cursor, I am able to do that.
Now I want that when I press a button it should change it's back and fore colors so that it looks selected.
I tried to do that by code but it's not working. Following is my css file content:
.buttonclass
{
background-color: Olive;
cursor: pointer;
}
.selectedItemClass
{
background-color: Blue;
color: White;
}
and on the button click I have written like:
Button btn = sender as Button;
btn.CssClass = "selectedItemClass";
but it's not working any idea or another way to achieve the required behavior.
Your code will only work after post-back, and then the button will remain with the selectedItemClass.
You will need to use client-side code to change the class of your button.
One option would be to use a javascript/jquery solution like:
$(".buttonclass").mousedown(function(){
$(this).addClass("selectedItemClass")
});
$(".buttonclass").mouseup(function(){
$(this).removeClass("selectedItemClass")
});
Have you checked if the class is added or replaced? or you can do:
.selectedItemClass
{
background-color: Blue!important;
color: White!important;
}
to check if the order of your css is ignoring the fact there are two different background-color and the priority of them.

Qt Stylesheet syntax: targeting a specific button, not ALL buttons

I have a window with two buttons.
I'd like to decorate each one with a different stylesheet. They both have different object names, of course, but it seems that only the generic QPushButton stylesheet selector works.
I tried:
QPushButton#myBtnObjectName1 {
/* style definitions */
}
QPushButton#myBtnObjectName2 {
/* style definitions */
}
Tried the same with replacing the # with a ., or having the #myBtnObjetNameX only. Nothing works. Just:
QPushButton {
/* style definitions */
}
Am I using a wrong syntax? Or is this simply impossible without deriving from QPushButton in code and using a separate class name for each?
To match instances using the objectName, you can also use the selector ^=. According to the standard:
[att^=val] Represents an element with the att attribute whose value
begins with the prefix "val".
Example in Qt:
QPushButton[objectName^="push"] { background-color: red; }
A QPushButton called pushButton would be matched, but not an object called pbt.
You can use "accessibleName" in Qt Designer for this.
And in qss stylesheet:
more universal:
[accessibleName="alert-error"] {
color: red;
}
or be more specific:
QPushButton[accessibleName="bigred"] {
background-color: red;
}
Ah yes, the "AccessibleName" in Qt Designer needs to be set too, not just "ObjectName"

Resources