Reputation: 149
So I'm having an issue with stylesheets in PyQt5. Im trying to make a custom scrollbar for my QListWidget, and it works fine in the QtEditor, but doesn't work when running the actual code or when previewing in the Designer. Heres the stylesheet:
QTableWidget{
border-radius: 10px;
background-color: transparent
}
QHeaderView::section{
background-color:transparent;
border-radius:10px;
}
QTableWidget::item{
border-radius: 10px;
background-color: rgb(92, 95, 141);
margin-bottom: 3px;
margin-right: 3px;
}
QTableWidget::item:selected{
color: rgb(255, 255, 255);
background-color: rgb(143, 154, 255);
border: 0px;
}
QScrollBar:vertical {
border: 0px solid #999999;
background-color: rgb(34, 35, 52);
width:14px;
margin: 0px 0px 0px 3px;
}
QScrollBar::handle:vertical {
min-height: 0px;
border: 0px solid red;
border-radius: 5px;
background-color: rgb(92, 95, 141);
}
QScrollBar::add-line:vertical {
height: 0px;
subcontrol-position: bottom;
subcontrol-origin: margin;
}
QScrollBar::sub-line:vertical {
height: 0 px;
subcontrol-position: top;
subcontrol-origin: margin;
}
When I use look at in the Qt Designer, it works fine
But when I preview the scrollbar in Designer, it appears as the default scrollbar.
I also tried running the code in python and had the same result. So why does the Designer show that the stylesheet works fine, but it actually doesn't work at all?
Edit: Problem was fixed by applying the scrollbar stylesheet to a parent element of the scrollbar.
Upvotes: 1
Views: 3441
Reputation: 48424
Ensure that you're not using generic stylesheets; for instance, in the provided ui file, change the stylesheet of TaskScreen to:
QFrame#TaskScreen {
background-color: rgb(34, 35, 52);
}
When setting stylesheets on Qt widgets, it's important to be aware about two aspects:
The problem with the first point is that many widgets are actually complex widgets that have children widgets (sometimes unacessible even at programming level, but will still behave as QWidgets), most importantly all classes that inherit from QAbstractScrollArea (such as item views) always have two scroll bars, and since those scrollbars are direct children of the scroll area, they will inherit the parent stylesheet.
The problem with the second point is that properties set with universal or generic selectors can behave in unexpected ways depending on the widget that applies them.
While using these stylesheets is fine for very simple widgets that don't have children (QLabel, QPushButton), with complex widgets it can become an issue, especially if they have sub-controls that require more thorough styling.
This important note in the stylesheet syntax documentation must always be considered:
Note: With complex widgets such as QComboBox and QScrollBar, if one property or sub-control is customized, all the other properties or sub-controls must be customized as well.
While you did customize almost all properties, you also set a generic property for a parent widget (the TaskScreen QFrame, in the UI example):
background-color: rgb(34, 35, 52);
The result is that all of its children and grandchildren, no matter what class they are, will have that priority property set, and considering the above note, the result is that the stylesheet is not properly used, as the Qt stylesheet style parser finds that a property is set but is missing other important ones.
The solution is to properly use a type selector for the parent:
QFrame {
background-color: rgb(34, 35, 52);
}
If you want to ensure that only that object uses that background, you can use a more specific selector, the most common is the object name selector:
QFrame#TaskScreen {
background-color: rgb(34, 35, 52);
}
Or, alternatively, the class selector, that maches only instances of that class but not subclasses of it:
.QFrame {
background-color: rgb(34, 35, 52);
}
This is important, as there are actually a lot of classes that inherit from QFrame, including QLabel and all those based on QAbstractScrollAreas as cited above.
Beside what explained above, as a rule of thumb it's normally better to avoid styling each widget individually: you may end up setting a generic stylesheet on a parent and then you forget about it, then after lots of modifications you could notice unexpected behaviors like yours and it's really annoying to find out where the problem actually is.
It's usually a better approach to set a "main" stylesheet (set on the top level window, the main window, or even the QApplication), with proper usage of selectors and careful inheritance of properties and states, and then only change small properties on the specific widgets for which you want to alter default appearance.
Upvotes: 1