使用QSS设置QAbstractSpinBox样式时,从QColorDialog中的QSpinBoxes中排除样式

时间:2019-02-21 18:38:33

标签: css qt qtstylesheets

我一直使用Jorgen-VikingGod出色的Qt-Frameless-Window-DarkStyle作为基线,使用QSS设计Qt桌面应用程序。不幸的是,我们还必须在现场支持过时的平板电脑设备(运行Windows),这意味着微小的旋转框按钮实际上对我们的某些客户不可用。

建议的解决方案是创建大的+/-按钮并将其放在旋转框的相对侧:

SpinBox with big buttons

但是,这会导致某些Qt便利控件(例如QColorDialog)出现不良行为:

Bad 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,所以如果我可以排除特定的子类,那也就足够了。 / p>

2 个答案:

答案 0 :(得分:1)

您可以使用CSS / QSS为QColorDialog的某些组件设置样式。

enter image description here

因此您可以添加以下内容:

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

为旋转框添加一些额外的内容。我还将最小宽度最小高度添加到 QColorDialog QColorPicker 中,如下所示:

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

答案 1 :(得分:0)

谢谢您的起点!!!在与Qt 5.9.2进行了很长时间的斗争之后,我发现了如何将“按钮”恢复为默认/本机状态:

QColorDialog QPushButton {background-color:native; color:native; border: native; border-radius:-1px; padding: 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;

即使您告诉您将边框设置为本地,如果您之前已设置边框半径,它也会回退到 ... 您必须提供一个无效的半径值。半径存储在QSize中,该值对于-1,-1,-1,-1无效。

将导致 hasNativeBorder 失败,导致根本没有边框/背景...

为什么不是简单的 qt-all-native:true 或类似的QSS扩展...