QT StyleSheet Theme for entire application using attribute selectors - c++

Background:
I have a Qt application consisting of multiple dialogs and windows. I am trying to condense all styles into a single stylesheet which I want to load in my main.cpp with the aim of it being applied to my whole application (as I understand one should do). The application should not change styles from this point onwards.
I want to do this as styles can get mixed up, etc if one does this or something simliar for each widget in the QtCreator designer.
Problem:
I will explain a specific problem I face with an example from my application.
I have a couple of variations of simple dialogs, QLabel title, QLabel message (sometimes a QLabel hint), and either a single 'ok' QPushButton or 2 QPushButtons 'positive' & 'negative'.
For my theme, I would like to set styles for specific buttons, labels, etc which I got from here.
Example CSS:
QPushButton {
font-size: 10pt
color: #111
}
QPushButton[objectName="btnPostive"][objectName="btnProceed"] {
font-size: 1pt
color: #ccc
}
QLabel {
font-size: 9pt
color: #111
}
QLabel[objectName="lblTitle"] {
font-size: 9pt
color: #111
}
Please note, the [objectName="btnPostive"][objectName="btnProceed"] is intended to apply the style to buttons with the objectName's btnPostive and btnProceed however, it does not.
Is what I intend doing considered best practice, and a sub question (preferred example too) applying the same style to a select group of widgets, how should one best this.

If you want to control the applied stylesheet based on the object name, you can use the ID Selector QPushButton#objectName, see the full documentation. You separate multiple objects with the same stylesheet with a ,
Your stylesheet should then be this. Please note that you also need a ; at the end of each line.
QPushButton {
font-size: 10pt;
color: #111;
}
QPushButton#btnPositive, QPushButton#btnProceed {
font-size: 1pt;
color: #ccc;
}
QLabel {
font-size: 9pt;
color: #111;
}
QLabel#lblTitle {
font-size: 9pt;
color: #00f;
}

Related

How can I set background for a QPushButton's tooltip?

In Qt I set a background image for a QPushButton, then I added a tooltip for this button and the tooltip has the same background image as the button and I couldn't change it with stylesheet, what am I missing?
In my code I have:
button->setStyleSheet("background-image: url(pathToImage);");
button->setToolTip("Click here");
In my style.qss I have:
QToolTip{
background-image: none;
background-color: white;
font-size: 20px;
border: 1px solid black;
}
The font-size and the border works, but the tooltip's background-image is the same as the button's.
I also tried adding another background-image to the tooltip, it didn't worked either.
How can I change the tooltip's background?
You have to specify the QWidget where to apply the property. If you dont do so, it will apply it to all the childrens of the widget.
In your case, to avoid the background image in the tooltip you have to specify that you want to apply that style to a QPushButton widget. The documentation says:
If we want the property to apply only to the QLineEdits that are children (or grandchildren or grand-grandchildren) of a specific dialog, we would rather do this:
myDialog->setStyleSheet("QLineEdit { background-color: yellow }");
In the example you mention, if you want to modify the style of the tooltip and the button, do something like this:
ui->pushButton->setStyleSheet(""
"QPushButton { background-image: url(me.png); }"
"QToolTip { color: #ffffff; background-color: #000000; border: 0px; }");
It will give you something like this
Update:
If you want to apply it to a single object and not the rest of the widgets of the same type, the documentation says:
If we want the property to apply only to one specific QLineEdit, we can give it a name using QObject::setObjectName() and use an ID Selector to refer to it:
myDialog->setStyleSheet("QLineEdit#nameEdit { background-color: yellow }");
So in your case:
ui->pushButton->setObjectName("awesomeButton");
ui->pushButton->setStyleSheet("QPushButton#awesomeButton { background-image: url(me.png); }");
When you set qss with setStyleSheet your stylesheet applies for all children of object. In your case you can avoid this using stylesheet for QPushButton only
button->setStyleSheet("QPushButton {background-image: url(pathToImage);}");

How can I remove the "padding" of a QTabWidget?

I have a QTabWidget with a QTableWidget inside, as the example below:
But it has a "padding" (at least I think it is a padding) in the QTabWidget (marked as red in the figure).
How can I remove that or expand the QTableWidget to fill the QTabWidget area?
I am using Qt 5.3.
Try something like this :
tabwidget.setStyleSheet("QTabWidget::pane {
margin: 0px,1px,1px,1px;
border: 2px solid #020202;
border-radius: 7px;
padding: 1px;
background-color: #E6E6E3;
}");
Hope this help you
The problem seems to be related to the "pane" margin of the QTabWidget.
I solved the problem by using this on the stylesheet:
QTabWidget::pane {
border: 0 solid white;
margin: -13px -9px -13px -9px;
}
When you put QTableWidget to QTabWidget tab, you can right click on it (QTabWidget) and select Lay out -> Lay out vertically (for example, or horizontally), this will add an verticalLayout element and place your QTableWidget into it, filling the whole tab. Then, select newly created verticalLayout, scroll down to Layout section, and from here you can control layoutLeftMargin, layoutTopMargin, layoutRightMargin and layoutBottomMargin properties:
Setting all of them to 0, will give you desired result (no stylesheets involved):

How to stop child QTabWidget to inherit style sheet from parent QTabWidget

I have done below styling on QTabWidget (which has a QTabWidget inside one of it's tab):
QTabBar::tab {
border: 2px solid grey;
}
QTabBar::tab:selected {
border-color: red;
}
After this the tab widget looks like:
I do not want child QTabWidget to inherit style from parent. I know one way to achieve this is by using object name in style sheet but I don't have the object name of QTabBar associated with QTabWidget. Please let me know how I can achieve the desired behavior.
You can use object name on the QTabWidget:
parent_tab_widget->setObjectName("parent_tab_widget");
In style sheet:
#parent_tab_widget > QTabBar::tab {
border: 2px solid grey;
}
#parent_tab_widget > QTabBar::tab:selected {
border-color: red;
}
More info on style sheet selectors in Qt4 here. The answer is a combination of the ID selector with the child selector.

Set border for QSpinBox when focused

For already existed Qt project I'd like set border for focused widgets through qss-fle. But I faced out with some unexpected result. When I change border of QSpinBox (and QDoubleSpinBox) border will change as I expect but up-button and down-button change too and look ugly.
Here is my style definition (full example available here):
QSpinBox:focus
{
border-width: 2px;
border-style: solid;
border-color: green;
}
My question is: how to change appearance of border and simultaneously preserve appearance of up-button and down-button. Solution what I am looking for shouldn't be cross platform or cross version.
My environment:
- KUbuntu 15.10 (amd64);
- Qt 5.4 (x64).
Update:
Here is one more example with another style:
QSpinBox
{
border-width: 2px;
border-style: solid;
border-color : red;
}
QSpinBox:hover
{
border-width: 2px;
border-style: solid;
border-color: blue;
}
The widget looks like this:
When you apply a style sheet to the QSpinBox, this widget is completely painted using the QStyleSheetStyle (this class is not part of the public API).
So you have to either style your spin box completely, including the up/down buttons or not to use the style sheet at all.
That up/down buttons are not separated widgets, so you can't apply a different style to them.
So I suggest to subclass the QSpinBox and reimplement the paintEvent() method. In your paintEvent() method you will just call it's default implementation and than you will draw a rectangle around.
try to edit your qss file with another random style to see if it's consistent.
QSpinBox
{
border-width: 2px;
border-style: solid;
border-color : red;
}
QSpinBox:hover
{
border-width: 2px;
border-style: solid;
border-color: blue;
}
Edit :
I see that your arrows are still in bad form so I would suggest you two things :
style also your up-down arrows with background image property or so (take a screen shot of the desired arrows..or so)
forger to style this part via stylesheet and override the "QPaintEvent onFocus handler" by code. Setting the border as green wouldn't be so painful

How does view's stylesheet interact with model's ::FontRole in Qt model/view environment?

What happens when font family and size supplied by stylesheet of QTreeView differ from the ones returned by the model assigned to it? So far it seems like model's data overrides stylesheet settings. How do I change font of a view with a custom model assigned to it then?
Or to be more precise: if I know I want to style the view with stylesheet - what do I return from model when ::FontRole is requested?
UPD: just in case I am doing something stupid, here is my stylesheet that I assign to qtreeview:
QTreeView::item:selected
{
color: black;
font-family:"Times New Roman", Times, serif;
}
QTreeView::item:has-children
{
font-family: "Comic Sans MS", cursive, sans-serif;
height: 25px;
border-bottom: 1px solid;
border-bottom-color: green ;
border-top: 1px;
}
After some asking around and googling it turned out that styling text in QTreeView should be done on QTreeView instead of QTreeView::item