pyapp-kit / superqt

Missing widgets and components for Qt-python
https://pyapp-kit.github.io/superqt/
BSD 3-Clause "New" or "Revised" License
210 stars 38 forks source link

Problem with themes (e.g. qdarkstyle) #58

Open piplus2 opened 2 years ago

piplus2 commented 2 years ago

Describe the bug Using global stylesheets (such as qdarkstyle) breaks the QRangeSlider visualization.

To Reproduce Steps to reproduce the behavior: Used the example stylesheet for QLabeledRangeSlider and then set the qdarkstyle style sheet to the MainWindow.

This is my style sheet for the slider:

QSS = """
QSlider {
    min-height: 10px;
}

QSlider::groove:horizontal {
    border: 0px;
    background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #888, stop:1 #ddd);
    height: 10px;
    border-radius: 5px;
}

QSlider:focus {
  border: none;
}

QSlider::handle {
    background: qradialgradient(cx:0, cy:0, radius: 1.2, fx:0.35,
                                fy:0.3, stop:0 #eef, stop:1 #002);
    height: 10px;
    width: 10px;
    border-radius: 5px;
}

QSlider::handle:horizontal:hover {
    background: qradialgradient(cx:0, cy:0, radius: 1.2, fx:0.35,
                                fy:0.3, stop:0 #efe, stop:1 #222);
}

QSlider::sub-page:horizontal {
    background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #227, stop:1 #77a);
    border-top-left-radius: 5px;
    border-bottom-left-radius: 5px;
}
"""

QSS += """QRangeSlider {
    # This function just defines the stops for the gradient
    qproperty-barColor: """ + gen_style_string_from_hex_colors(
    colormap='viridis') + \
       """\n}"""

This is how I set the qdarkstyle theme:

import qdarkstyle
...
app = QtWidgets.QApplication(sys.argv)
m = MainWindow()
style_sheet = qdarkstyle.load_stylesheet()
m.setStyleSheet(style_sheet)

Screenshots

Without qdarkstyle (I've customized the barColor with a gradient):

image

With qdarkstyle:

image

Desktop (please complete the following information):

jingxuxie commented 2 years ago

I do encounter the same problem. When I tried to use the qdarkstyle with qrangeslider which has two handles, one of the handle disappear.

jingxuxie commented 2 years ago

But I guess this is more about an issue related to the qdarkstyle?

jingxuxie commented 2 years ago

After some test, I believe this is not a problem of qdarkstyle, this might be a bug of setting style in _generic_range_slider.py

tlambert03 commented 2 years ago

Thanks, yes the range slider does rely on a few internal styles (though, I would have expected it to affect mostly the inner bar color, not the handles themselves, unless qdarkstyle is overriding the handle as well?) I'm aware we need to make qrangeslider a bit more robust to custom styles (see also https://github.com/napari/superqt/issues/35) but I'm afraid I don't have the bandwidth to dig deeper in to this at the moment. Any help debugging would be greatly appreciated here!

jingxuxie commented 2 years ago

After checking the style.qss file in qdarkstyle. I found that this can be solved by adding the following to the qrangeslider QSS style, this will be consistent with the Light plate in qdarkstyle. You can change the qproperty-barColor so that it has a consistent color with the dark theme:

QSS = """
QSlider{
 background-color: none;
}

QSlider::add-page:vertical {
  background: none;
  border: none;
}

QRangeSlider {
      qproperty-barColor: #9FCBFF;
}
kevinjohncutler commented 2 years ago

Interestingly, the label clipping only occurs when the range is asymmetric (i.e. -5 to 5 shows up fine, but 0 to 5 exhibits clipping). For example (mask threshold symmetric interval, flow threshold asymmetric interval):

image

I found the primary line in pyqtdarktheme causing this:QAbstractSpinBox {padding: 3px 4px;}. Removing it produces

image

Now it is legible, but the bar endpoints on the right do not line up. Is there any way to set a fixed width?

tlambert03 commented 2 years ago

thanks @kevinjohncutler ... good find. pixel precise styles with arbitrary style sheets is definitely a challenge!

for what it's worth, i think the key bit of label-positioning code on the superqt side is probable right here:

https://github.com/napari/superqt/blob/e7e8dfc44c4c984126e52385015eed4942519f87/src/superqt/sliders/_labeled.py#L321-L345

I don't have time to play with it at the moment, but if you're so inclined, i think I'd probably start tweaking there.