在paintEvent中绘制Qt控件并遵守样式表属性

4

在Qt中是否有类或方法可以获取属性,例如"border-color"、"border-style"等。

这对于基于当前选定的样式表创建和绘制自己的(派生)控件可能是有用的。

示例:

QPushButton {
    border: 3px solid red;
    background: blue;
    margin: 5px;
    padding: 10px;
}

代码:

class QPushButtonCircle : public QPushButton {
};

QPushButtonCircle是一个圆形按钮,连边框也是圆形的。边框宽度应为3像素,实心且颜色为红色。背景应该是蓝色。

我没有找到任何方法,除了完全在paintEvent中绘制并忽略任何样式表。但必须有更好的方法。

最好的办法是:

QCssStyle cssStyle = widget->...->getCssStyle();

QPen border = cssStyle->border(QCssStyle::Top);
QBrush background = cssStyle->background();
QMargins margins = cssStyle->margins();
QMargins padding = cssStyle->padding();
...

这将允许我们像这样绘制自己的控件:
QStylePainter p(this);

QRect r = rect();
r.adjust(cssStyle->margins().left(), ...);

p.setPen(cssStyle->border());
p.setBrush(cssStyle->brush());
p.drawEllipse(r);

r.adjust(cssStyle->padding().left(), ...);
p.drawText(r, ...);

更好的解决方案是使用类似于QStyle::drawControlQStyle::drawPrimitive等方法,但要尊重QPainterPath(或更简单的基本图形),而不是假设控件为矩形。

在Qt中创建从样式表派生颜色的自绘控件的最佳方法是什么?


哇,那将是一个非常好的东西,但是现在还没有。也许你可以通过使用某个解析器(https://dev59.com/eUbRa4cB1Zd3GeqPwQBl)将其作为`QString` css属性的包装器来实现它。但是如果不涉及Qt内部,处理这个问题会很困难:小部件的stylesheet属性不是完整的计算样式:父级和qApp也会影响。这可能是向Qt开发人员提出功能请求的原因... - NIA
1个回答

0
我没有找到其他方法,除了在paintEvent中完全绘制并忽略任何样式表。但肯定有更好的方法。
Qt中的小部件是矩形,不能有其他形状。看看盒子模型。因此,任何其他方法都会像您尝试使用的方法一样棘手。 有一个建议使用QGraphicView
编辑:

我自己从未尝试过,但你可以尝试在按钮上设置一个蒙版并选择想要的形状,可以使用QBitmapQRegion。其他的css元素(颜色等)可以通过更新样式表来设置。如果能够使其正常工作,那么这是一种避免麻烦的解决方案,因为您无需处理自定义绘制事件。


QGraphicsView将完全忽略样式表。顺便说一下,QDial也是一个圆形控件,它会忽略样式表,除了像“background-color”这样的东西,因为更改这些颜色将更新该控件的调色板。看来Qt开发人员只在这里使用调色板。顺便说一下,设置背景颜色是我唯一可以从样式表中更改的属性。其他属性都被忽略了。 - bkausbk
你没有尝试使用圆形区域来掩盖吗? - UmNyobe
我之前测试过蒙版,但这并不能解决我的问题。蒙版只保证某些部分不被绘制(且不可见)。对于圆形按钮,这意味着整个边框都是不可见的。这可能对特别设计的闪屏有用,但对于控件来说则不是。 - bkausbk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接