Исключение стиля из QSpinBoxes в QColorDialog при использовании QSS для стиля QAbstractSpinBox

Я разрабатывал настольное приложение Qt с использованием QSS, используя превосходный https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle от Jorgen-VikingGod в качестве базовой линии. К сожалению, мы также должны поддерживать довольно устаревшее планшетное устройство (которое работает под управлением Windows) в полевых условиях, что означает, что крошечные кнопки спин-бокса были фактически непригодны для некоторых наших клиентов.

Предлагаемое решение состояло в том, чтобы создать большие кнопки +/- и поместить их по разные стороны от спин-бокса:

Однако это приводит к плохому поведению с некоторыми удобными элементами управления Qt, такими какQColorDialog:

Мой код QSS выглядит следующим образом:

QAbstractSpinBox {
  height: 18px;
  border-radius: 2px;
  border: 1px solid rgba(38,38,38,255);
}
QAbstractSpinBox:focus {
  border-color: palette(highlight);
}
QAbstractSpinBox::up-button {
  subcontrol-origin: border;
  subcontrol-position: center right;
  width: 18px;
  height: 18px;
  border-image: url(:/darkstyle/icon_spin_box_button.png);
  margin-left: 1px;
}
QAbstractSpinBox::down-button {
  subcontrol-origin: border;
  subcontrol-position: center left;
  width: 18px;
  height: 18px;
  border-image: url(:/darkstyle/icon_spin_box_button.png);
  margin-right: 1px;
}
QAbstractSpinBox::up-button:pressed {
  border-image: url(:/darkstyle/icon_spin_box_button_pressed.png);
}
QAbstractSpinBox::down-button:pressed {
  border-image: url(:/darkstyle/icon_spin_box_button_pressed.png);
}
QAbstractSpinBox::up-arrow {
  image: url(:/darkstyle/icon_spin_box_plus_sign.png);
  width: 14px;
  height: 14px;
}
QAbstractSpinBox::down-arrow {
  image: url(:/darkstyle/icon_spin_box_minus_sign.png);
  width: 14px;
  height: 14px;
}
QAbstractSpinBox::up-arrow:disabled,
QAbstractSpinBox::up-arrow:off {
  image: url(:/darkstyle/icon_spin_box_plus_sign_disabled.png);
  width: 14px;
  height: 14px;
}
QAbstractSpinBox::down-arrow:disabled,
QAbstractSpinBox::down-arrow:off {
  image: url(:/darkstyle/icon_spin_box_minus_sign_disabled.png);
  width: 14px;
  height: 14px;
}

До сих пор я пытался заменить QAbstractSpinBox селекторы с .QSpinBox, .QDoubleSpinBox, но это привело к путанице, которая выглядела как гибрид стиля по умолчанию (стрелки вверх / вниз, сложенные справа) с моим стилем (темные границы, выпуклый вид и т. д.).

Похоже, что QSS не поддерживает стиль CSS3 :not селектор, и при этом это не обеспечивает эквивалент, который я могу использовать.

Учитывая все вышесказанное, могу ли я применить этот стиль к каждому спин-боксу в моем приложении, кроме тех, что в QColorDialog? Или какая-либо альтернатива, которая не требует от меня установки этого стиля по ID/objectName для каждого отдельного экземпляра прядильного окна, которое есть в моем приложении? Просматривая исходный код, кажется, что QColorDialog использует QSpinBoxкласс по имени QColSpinBox, так что если я могу исключить определенный подкласс, то это также будет достаточно хорошо.

0 ответов

Вы можете стилизовать некоторые компоненты QColorDialog с помощью CSS/QSS.

Таким образом, вы можете добавить что-то вроде этого:

QColorDialog QSpinBox {
    min-width: 3.5em;
    text-align: center;
}

чтобы добавить дополнительное пространство для спин-боксов. Я также добавляю минимальную ширину и минимальную высоту в QColorDialog QColorPicker следующим образом:

QColorDialog QColorPicker {
    min-width: 20em;
    min-height: 20em;
    border: solid 1px gray;
}

Спасибо за отправную точку!!! После очень долгой борьбы с Qt 5.9.2 я нашел, как вернуть кнопки в исходное состояние по умолчанию:

QColorDialog QPushButton {background-color:native; color:native; border: native; border-radius:-1px; padding: native;}

Здесь нет ни авто, ни значения по умолчанию.

native - это ключ, но для границы и фона вы должны отменить любой радиус границы из-за следующего кода:

void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
                                          const QWidget *w) const
{
    RECURSION_GUARD(baseStyle()->drawComplexControl(cc, opt, p, w); return)

    QRenderRule rule = renderRule(w, opt);

    switch (cc) {
    case CC_ComboBox:
        if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
            QStyleOptionComboBox cmbOpt(*cmb);
            cmbOpt.rect = rule.borderRect(opt->rect);
            if (rule.hasNativeBorder()) {
                rule.drawBackgroundImage(p, cmbOpt.rect);
                rule.configurePalette(&cmbOpt.palette, 
            ...
            ...
            ...

... ... ...
bool hasNativeBorder() const {
    return bd == 0
           || (!bd->hasBorderImage() && bd->styles[0] == BorderStyle_Native);
}
... ... ... 
void QRenderRule::fixupBorder(int nativeWidth)
{
if (bd == 0)
    return;

if (!bd->hasBorderImage() || bd->bi->pixmap.isNull()) {
    bd->bi = 0;
    // ignore the color, border of edges that have none border-style
    QBrush color = pal ? pal->foreground : QBrush();
    const bool hasRadius = bd->radii[0].isValid() || bd->radii[1].isValid()
                           || bd->radii[2].isValid() || bd->radii[3].isValid();
    for (int i = 0; i < 4; i++) {
        if ((bd->styles[i] == BorderStyle_Native) && hasRadius)
            bd->styles[i] = BorderStyle_None;

Даже если вы скажете, чтобы установить границу родной он будет падать назад никто, если вы ранее настройки границы радиус... Yous должен дать недопустимое значение радиуса. Радиус сохраняется в формате QSize, который недопустим для -1, -1, -1, -1.

никто не сделает hasNativeBorder неудачным, что приведет к отсутствию границы / фона вообще...

Почему не простое qt-all-native: true или подобное расширение QSS...

Другие вопросы по тегам