Programmatically retrieve values for QSS style sheet properties - c++

If I have a label that has a margin that is set using setMargin(), then I can use margin() to get the value.
But when if I set the padding using a style sheet?
ui->label->setStyleSheet("QLabel {padding: 0px 5px 10px 15px;}");
How can I get the values programmatically? Is there a function that will give me the value for a given property in the style sheet? Is there a function like ui->label()->styleSheet->getProperty("padding:left")?

I've not found any way to give all properties. I think it doesn't exist for architectural reasons. But you can take most of it from QWidget substrucrutes. For example you may take background-color from palette().color(QPalette::Window). If you want to supply qss background in your QWidget with overridden paint event you can do it this way:
void PulseChart::paintEvent(QPaintEvent*)
{
QPainter p{this};
p.fillRect(QRect{QPoint{0,0}, this->size()}, palette().color(QPalette::Window));
}

Related

Qt read dynamic qproperties in stylesheets

I'm writing an application that contains widgets with different Qt-properties. One of these properties is a simple color-property:
Q_PROPERTY(QColor color GET color SET setColor NOTIFY colorChanged)
I would like to be able to access this property from within a stylesheet to change how the widget looks.
The stylesheet will be supplied by a user and cannot be dynamically created within the application.
I do not know what the user wants to make the application look like, but I want to give them the opportunity to set colors (and other properties) based on dynamic properties of the widget:
MyWidget {
border: 1px solid red;
background-color: <color property value>
}
In terms of color, according to the Qt documentation, the desired behaviour should be possible by accessing the widget's palette:
MyWidget {
border: 1px solid red;
background-color: palette(window);
}
However, as numerous people have already reported, this doesn't seem to be working as intended, since the stylesheet doesn't access the widget's own palette, but the application palette instead.
As mentioned in the Qt wiki, one can access dynamic properties by using either a selector for reading, or using qproperty- as a prefix for writing.
The stylesheet for writing a custom property looks like this:
MyWidget {
border: 1px solid red;
qproperty-color: red;
}
Reading a custom property using a property-selector looks like this:
MyWidget[color="red"] {
border: 1px solid red;
}
(note: i'm not sure if this selector would actually work, I haven't tried this with colors).
Now this would work for my case if I had a small set of possible colors.
However, my application computes a color dynamically, which would result in 2^24 (not counting alpha) colors.
Seeing that write access to properties can be obtained by using qproperty-color: <value>;, i'd have expected read access to be syntactically symmetrical:
MyWidget {
border: 1px solid red;
background-color: qproperty-color;
}
However, this doesn't work, hence me posting here.
Has anyone found any other way to access properties and using them in stylesheets to change the way widgets look without knowing the possible values beforehand?
I had a similar problem around a month back, and I also tried to solve it with StyleSheet but ultimately ditched the idea of using StyleSheet for QPalette.
Using StyleSheet to change the widget's look is a lot of work, especially if the widget is resizable. I would suggest using QPalette instead. However, with QPalette there is a catch: some styles, especially the default ones like window doesn't let you override all the properties of the palette of that style. I would suggest changing the default style of your application to fusion and using its palette in your application:
#include "mainWindow.h"
#include <QtWidgets/QApplication>
#include <QStyleFactory>
#include "start.h"
int main(int argc, char *argv[])
{
QApplication::setStyle(QStyleFactory::create("Fusion")); // Setting Fusion Style
QPalette light = QApplication::palette(); // Getting Fusion Style Palette
Start S(light); // Making Changes to the palette
QApplication A(argc, argv);
mainWindow W(&S, &A); // Passing the palette to main window so that you can change it dynamically
W.show();
return A.exec();
}
Using fusion style has many advantages:
Supports customization of almost all ColorGroup and ColorRole
Has a dark theme: FusionDarkTheme
Easier to maintain than StyleSheet
To be able to change the background of your widget you will also have to set it's autoFillBackground value to true otherwise its parent's background will override the widget's background. It's one of the reasons why you are unable to change the background color of your widget. You don't have to make the change individually for each widget, you can do it like this:
void mainWindow::setAutoBackgroundForWidget()
{
QList<QWidget *> widgets = this->findChildren<QWidget *>();
for(QWidget *wid : qAsConst(widgets))
{
QList<QByteArray> pro = wid->dynamicPropertyNames();
if(!pro.isEmpty())
{
for(QByteArray byt : qAsConst(pro))
{
if(byt == "Level")
{
wid->setAutoFillBackground(true);
}
}
}
}
}
The above function setAutoBackgroundForWidget() is a function created by me which I call before the end of the constructor of mainWindow. This function selects all widget, which has a dynamic property named "Level" to have its own background instead of using its parent's background. You can modify the above function accordingly to select the widgets that you need.
After you are done with the above, all that is left is to use QColorDialog to ask your users which color they need, copy the current palette and change the given ColorRole in it to the new color and apply the new palette to your widget using setPalette(). You can also do it in a single function inside your mainWindow cpp file for all your widget.
As for the StyleSheet, I can confirm that following works:
MyWidget[color="red"] {
border: 1px solid red;
}

Qt QTabWidget background color

I have been trying to set the background color of a QTabWidget to black (or any other color for), but have been unsuccessful in doing so.
It seems that you need the option autoFillBackground set and then also set "background-color: black;" in the stylesheet. This then displays it properly in the Designer, but fails in the application.
This answer suggests to enclose it in another QWidget and then use the transparency, but that is a hack around the issue.
How do I set the background color of a QTabWidget via stylesheets?
EDIT
Setting QTabBar { background-color: black; } results in the following image.
As an alternative to QTreeWidget, use QTabBar + QStackedWidget and the following stylesheet
QTabBar { background-color: black; }
or use
Qt: Styling QTabWidget

Qt/C++ - Set background of disabled button?

I have all my buttons disabled in a grid, but for some, I'd like to change the background color. I'm trying:
_fieldButtons[0][0]->setStyleSheet("color: blue; background-color: blue;");
Where
QVector<QVector<QPushButton*> > _fieldButtons;
However, these buttons are all disabled, and only the text color gets changed:
How can I change the background, but not the text? Thank you!
UPDATE
I figured it's not working because the buttons are flat. How can I change flat button colors?
Two options:
Add border: none; to your stylesheet.
Use setAutoFillBackground(true) in conjunction with QPalette::Button
myButton->setFlat(true);
myButton->setAutoFillBackground(true);
QPalette pal = myButton->palette();
pal.setColor(QPalette::Button, QColor(Qt::blue));
myButton->setPalette(pal);
http://doc.qt.io/qt-5/qpushbutton.html#flat-prop
Try this:
myButton->setPalette(QColor("#124e6b"));
simply change the QColor to suit your use.
Or in Qt Creator you can right-click on the widget and select Change Style Sheet, as shown here:
Here you have two "Pseudo-States" in your control. For list of "Pseudo-States" refer below link.
http://doc.qt.io/qt-5/stylesheet-reference.html#list-of-pseudo-states
The first "Pseudo-State" is -- flat
The second "Pseudo-State" is -- disabled
Here you have to club both the states to set the style using "setStyleSheet".
_fieldButtons[0][0]->setStyleSheet(":flat:disabled {background-color: blue; border: none;}");
look for ":hover:enabled" (two different "Pseudo-States" how documentation handled) in the below link to get better idea.
http://doc.qt.io/qt-4.8/stylesheet-syntax.html
To understand, why you we have to give border:none for QPushButton, please look for below information in the first hyperlink in this answer.
"Warning: If you only set a background-color on a QPushButton, the background may not appear unless you set the border property to some value. This is because, by default, the QPushButton draws a native border which completely overlaps the background-color."

Qt stylesheet of dock area splitter

How to change the style sheet of splitter/handle beside QDockWidget when it is added to DockWidgetArea. There is one main movable handle and multiple handles between each dockwidgets on that side. I would like to change at least bg colour and border of the handle and hover colour.
It would help if I know what kind of object it is or to get some pointer to the handle to setStyleSheet on it.
Ok I found it after some digging inside source code. Finally the answer was so simple and was screaming from the documentation of style sheet:
Note: Use QMainWindow::separator to style the resize handle.
Ok so the code is simple:
QMainWindow::separator
{
background-color: green;
width: 4px;
border: none;
}

QLineEdit Rounded Corners?

Is there a way to round the corners of a QLineEdit widget? If not is there a similar widget I could do this to?
Visual Meaning:
Solved: (See below for additional information)
QLineEdit *lineEdit = new QLineEdit;
lineEdit -> setStyleSheet("QLineEdit { border: 2px solid gray;"
"border-radius: 5px;}");
You can use StyleSheets to set styles of Qt components just like you would use them in making a website. You can set a stylesheet in two ways: in your application's code, or in QtDesiner.
To do it in QtDesiner (which is most convenient), right-click on the component which you have placed on the form, and press "Edit StyleSheet" (or maybe "Change Stylesheet", sorry, my Qt is not it English, so I'm not sure about the exact name of the option). A window will open that will let you edit the element's style sheet.
It is very convenient because it has some useful options like adding resources or colors or fonts right there, and you just need to press a couple of buttons to set the option you need through the GUI without the need to type or even to know CSS syntax.
From the code, you can do it like this (example):
SomeComponent->setStyleSheet("QLineEdit { border-radius: 5px; }");
Here is the documentation about the stylesheets.
Use stylesheets. From http://doc.qt.io/archives/qt-4.7/stylesheet-examples.html:
QLineEdit {
border: 2px solid gray;
border-radius: 10px;
}
Also, you can always override paintEvent if you want to get your hands dirty.