How do I change css styles of a gtkmm combobox? - c++

Whenever a widget changes it's state, it is supposed to change its style. I have successfully implemented the signalizing, but I can't figure out how to change a combobox' style really.
The function that changes a widget's style:
{
static Glib::RefPtr<Gtk::CssProvider> css{nullptr};
if(!css) {
css = Gtk::CssProvider::create();
css->load_from_data(
"button {background-color: #fff9ed;}\
button:hover {background-color: #fff9ed;}\
button:active {background-color: #fff9ed;}\
//changing background-color: to color: does not make any difference
combobox {color: #fg_color;background-color: #fff9ed;}\
.entry {color: #fff9ed;}\
checkbutton {background-color: #fff9ed;}\
checkbutton:checked {background-color: #fff9ed;}");
}
return css;
}
This results in making a really tiny frame over the combobox. Here is the output:
Before:
After:
One can clearly see, that the background changes (see the arrowed, orange tips on the corners). But that's not useful, as the actual box covers 99% of the background. I haven't figured out how to change styles of the atual combobox button, which would solve my problem as well.

I found a solution for my problem.
I assume 'padding' for comboboxes were at 0px, so i added 'padding: 2px;' in the css string.

Related

How apply different stylesheet to a QComboBox and its placeholder?

I want to distinguish the placeholder text of a QComboBox using QStyleSheet by drawing the placeholder with a different color.
With Qt6, it's easy to set the placeholder text to a combo box from code if the combo box is editable:
if(someCondition)
myComboBox->lineEdit()->setPlaceholder("Some placeholder");
else
myComboBox->lineEdit()->setPlaceholder("Some other placeholder");
So far so good, but if I use a custom stylesheet, so the default grayish placeholder is gone, and it is drawn with the color property. I tried to filter by some property based on this question, but I was not successful.
This is the relevant part of the dark-theme stylesheet:
auto styleSheet = "QWidget {color: white; background-color: #505050}"
"QComboBox[text=\"\"] { color: #808080 }";
myComboBox->setStyleSheet(styleSheet);
Currently, this is the result, with white letters:
And this is the expected with a sightly gray color:
Also, I tried to filter to the QComboBox, to the QComboBox[currentText=\"\"] but no success.
To draw the placeholder with darker pen, you have to modify the stylesheet and set to the lineEdit of the QComboBox.
auto styleSheet = "QWidget {color: white; background-color: #505050}"
"QLineEdit[text=\"\"] { color: #808080 }";
myComboBox->setStyleSheet(styleSheet);
myComboBox->lineEdit()->setStyleSheet(styleSheet);
QComboBox has no option to handle the placeholder text, because that text is handled by the line edit it has. Therefore, to alter the look and feel of the placeholder, you must use it's QLineEdit. Note, that several properties not make any effect on the line edit, like the background-color or border to say some, because those are handled by the QComboBox.
Also, if it's not automatically updated, you need to connect the change of the text with the stylesheet update. In the owning widget, connect the text change signal to the update:
connect(ui->myComboBox->lineEdit(), &QLineEdit::textChanged, this
[&]{ style()->polish(ui->myComboBox->lineEdit()); });

Border of the button with the icon

In the constructor, I set the style for the form and buttons:
{
ui->setupUi(this);
this->setStyleSheet("QWidget {background: rgb(49, 54, 59); color: rgb(220, 221, 218); selection-color: lightyellow; selection-background-color: darkcyan;}"
"QPushButton::hover {color: darkcyan; border: 2px solid grey; border-radius: 3px};");
}
Next, in the properties (icon parameter) of the button, I added an icon via resources, I also set the icon size using the iconSize parameter - 20x20, I also set the flat - True parameter in.
And this is what I get when I hover the cursor over the button:
The size of the button itself is formed using the layout and the size is 32x26, when the picture is set to 20x20.
Please tell me how you can remove this gap between the picture and the border of the button?
I tried to set the button size statically, about 22x22 and then everything is more or less fine, but I don't want to resort to such a radical solution. Thanks.
Referring to Qt's box model, the gap between the border and the icon is the padding.
In the stylesheet, you can set the padding to 0 as followed padding: 0px;

QT StyleSheet Theme for entire application using attribute selectors

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;
}

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);}");

QMenuBar items style in inactive window

How to disable changing menuItems look in QMenuBar when window loses focus?
Now, when window has focus, menu items are clearly visible, but when it loses focus, items are gray, looks like disabled. I want them to look normal all the time.
My platform is Qt4 on Windows7.
Some simple screenshot of menu item on active and inactive window:
Use QStylesheets and leverage the states of your QMenuItems.
http://www.qtcentre.org/threads/37560-QPushButton-different-stylesheets-for-focus-pressed-released-combinations
QPushButton{ background-color: blue; }
QPushButton:disabled{ background-color: yellow; }
QPushButton:pressed{ background-color: orange; }
QPushButton:focus:pressed{ background-color: black; }
QPushButton:focus{ background-color: green; }
QPushButton:hover{ background-color: red; }
QPushButton:checked{ background-color: pink; }
http://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmenubar
The other option if you want to ignore stylesheets, you could try the palette.
http://doc.qt.io/qt-5/qpalette.html#details
The color groups:
The Active group is used for the window that has keyboard focus.
The Inactive group is used for other windows.
The Disabled group is used for widgets (not windows) that are disabled for some reason.
So you should be able to get the copy of the palette for your QMenuItem, copy the active palette into the inactive palette, and then call setPalette on your QMenuItem. Tada, now it always looks active.
Hope that helps.