QComboBox:focus Qt Style Sheet - qt

I have an editable combo box on the input form, which background must change when it receives focus. The following code works perfect for QLineEdit but has no effect on QComboBox.
QLineEdit, QComboBox { background-color: green; }
QLineEdit:focus, QComboBox:focus { background-color: red; }
Is it possible to make QComboBox behaves as expected like QLineEdit using only Qt style sheets?

You may need to do this by subclassing QLineEdit, and installing it into the combo box (with QComboBox::setLineEdit()). Then, override the focusIn() and focusOut() functions of QLineEdit, and set a style sheet with the appropriate background color in those functions.
Another way would be to install an event handler on the combo box, (and/or its associated QLineEdit) and trap focus in/out events, and change the style sheet then.

Related

Dynamically change JavaFX properties for specific classes in CSS

I am writing code that allows a user to build a theme for the application, so they need to be able to effectively communicate that they want to change something about some element of JavaFX.
Suppose I have a bar on the top of every view that lets a user change the way some set of things look: button, label, text, and so on.
Here is a basic stylesheet that I am working with. It just puts style on root and button.
basetheme.css
.root {
-fx-background-color: "teal";
}
Button {
-fx-background-color: "orange";
-fx-font-size: 2em;
-fx-text-fill: #0000ff
}
Right now, all the views I have would load this sheet each time they are loaded:
view.getStylesheets().add("views/basetheme.css");
The Button class and its fx properties here would apply to all buttons in the view.
This is the behavior I want. I want the user to have leverage over Button and its properties during runtime.
For instance, if they want to change Button's -fx-font-size property from -fx-font-size: 2em to -fx-font-size: 3em, they can do that. Is this possible?
Currently, I know setStyle will set properties on some elements, but I am looking for a way to do this for not just a single Button, Label, and so on, but for all them. I want there to be run-time changes. For instance, after a user changes some element like button and one of its properties, it reloads that view and the change is applied.
I want to do something like view.setStyle("Button: some properties") and then it add those properties to Button class or overrides it, instead of view.setStyle("some properties") adding properties to root. The latter would not recognize that the property goes on a button, let alone all Buttons in view.
The obvious reason why this might not work this way is that we are not really changing the css file when we do those inline setStyle calls, just setting over the existing property and thus that inline has higher precedence and is updated.
I know I could technically do somebutton.setStyle("some properties"), but I want the user to be able to modify properties for all Button elements by specifying it at the root of a view so the styles trickle down to subelements in the view. This makes things easier.
You could use CSSFx to constantly pull in a CSS file that has bee written by your app.

How to change group widget content background color in Qt Style CSS

I'm trying to change skin of a program that supports Qt Style CSS, but I don't have access to the source code. I need to change the background color of the groups inside a QWidget,
I tried with:
QWidget {
background-color: #4d4d4d;
}
But it changes the color of the whole window, but I can still see the rectangle semi-transparent (like black 95% opacity). What class do I need to edit to change that particular box?
You are changing the style for the class QWidget which is the base for any Qt widget.
If you want to change the style for the group only, that's the QGroupBox class.
QGroupBox{
background-color: #4d4d4d;
}
Some QSS examples in the doc : https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qgroupbox
If you want to set the style on a specific widget of the application you will need more information from the code.

How to hide circle from radio button and only show icon in qt?

I want user to select a theme which he wants to apply to the document.
So i have created a popup dialog which has multiple themes which are qradiobutton. But I want to display only icons and remove circle from the widget.
I have tried visible:hidden for the radio button but that didn't worked.
If you want to customize QRadioButton with style-sheets I suggest you check the reference documentation: https://doc.qt.io/qt-5/stylesheet-reference.html#qradiobutton-widget
You should also find useful the examples given in Qt documentation as it shows how to replace the check indicator by different images:
QRadioButton::indicator {
width: 13px;
height: 13px;
}
QRadioButton::indicator::unchecked {
image: url(:/images/radiobutton_unchecked.png);
}
QRadioButton::indicator:unchecked:hover {
image: url(:/images/radiobutton_unchecked_hover.png);
}
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qradiobutton
If you do this yo can just use the indicator to display the icon and leave the QRadioButton label empty.
However, I have to warn you, depending on which QStyle you are using, it could happen that using style-sheets destroys completely the style of a component. A general example is: you are using a style where buttons have round corners, you use style-sheets to change the font of the button and as a result the button does not have round corners anymore. This is caused by incompatibilities between some QStyle and the style-sheet mechanism. If you do not want to make a multi platform app, it might not be an issue as you will use only one style, but if you make an multi platform app, you have to check every possible style you platform can have on the different platforms.
So if you want to have a QRadioButton without indicator and not use style-sheets, you can do it in C++ directly by subclassing QAbstractButton. Just make sure you set your class to be autoExclusive so that is will behave like a radio button.
would you try this? ( visible => visibility )
input[type="radio"] {
visibility: hidden;
}
or
input[type="radio"] {
display: none;
}

Using QApplication::setStyleSheet to override QSS attributes set in Qt

I created a button in Qt and gave it the QSS attribute background-color: gray;, while my external stylesheet has set the QSS attribute of the same button to background-color: blue;. When I run the application the button is gray, even though the style sheet is applied after the QWidget::show() is called and just before QApplication::exec(), as shown below:
MyWidget w;
w.show();
...
app.setStyleSheet("..."); // contents of external stylesheet
return app.exec();
Is it possible to have QApplication::setStyleSheet() override the QSS attributes assigned to a Widget in Qt.
No, it is not possible to override the QSS attributes the way you want, and trust me, you don't want to. It is not the order in which you call setStyleSheet that matters. It is the hierarchy that matters first. The call order matters only on widgets which are situated on the same level of the hierarchy.
The reason is that the widget has its internal style rules defined which override the parent's style thus the application style in your case. It is a hierarchy that is respected. You can look at this in the following way:
Say you have a QWidget with the following child hierarchy:
QWidget
|__QPushButton
|
|__QFrame
| |
| |_QListView
|
|__QProgressBar
Let's say you want to customize the background-color to all the widgets in your hierarchy. If the call to QApplication::setStyleSheet() would overwrite the stylesheet properties for the children, it would be impossible for you to set a custom style for your children. That's why child widget's QSS properties overwrite parent widget's QSS properties.
Look at it like the usual way to look at widgets. QPushButton is shown on top of QWidget. QFrame is shown on top of QWidget. QListView is also shown on top of QWidget. Styles apply the same way.
What I recommend doing is having only one external QSS file in which you define everything you want.
EDIT:
As N1ghtLight pointed out QSS preserves the class inheritance hierarchy so if you set a property for a class all its derived classes will inherit that property. For example if you have the following stylesheet:
QAbstractButton {
background-color: red;
}
QPushButton {
color: blue;
}
All QPushButtons will have the background color red and the text color blue as the QPushButton inherits the background-color property value from QAbstractButton which is its ancestor while QAbstractButtons which are not QPushButtons will have the background color red but the text color will remain unchanged.
The example above used a type selector. You can apply the style to specific objects by using different selector types. You can see different selector types here.

How can I set the stylesheet of a certain element of Qmessagebox

I have made a QMessageBox in the following way:
msgBox.setText("Are you sure?");
msgBox.setStandardButtons(QMessageBox::Yes| QMessageBox::No);
msgBox.setStyleSheet("background-image: url(image)");
msgBox.exec();
Unfortunately using setStyleSheet on the messagebox sets the background for the buttons, the textbox and the actual msgbox. This is not wat I want. I want only the msgbox to have a background not the other components of the messagebox. I found out that using:
msgBox.button(QMessageBox::Yes)->setStyleSheet(...)
can be used to set the background on just the buttons. Is there a command with which I can set just the background of the msgBox, without adding a background to the buttons and the textbox?
You can limit to which elements the style will be applied by using a selector. So to only apply the style to the QMessageBox itself and not its children, you would use:
msgBox.setStyleSheet("QMessageBox { background-image: url(image) }");
For more details, see The Style Sheet Syntax - Selector Types.

Resources