主要思想是复制复选框绘图的默认实现并根据您的需要进行修改。我们在默认实现中得到标签矩形,所以我们只需要在这个地方绘制新元素并将标签向右移动。我们还需要调整尺寸提示,以便新元素和默认内容都适合最小尺寸。
class CustomCheckBox : public QCheckBox {
Q_OBJECT
public:
CustomCheckBox(QWidget* parent = 0) : QCheckBox(parent) {
m_decoratorSize = QSize(16, 16);
m_decoratorMargin = 2;
}
QSize minimumSizeHint() const {
QSize result = QCheckBox::minimumSizeHint();
result.setWidth(result.width() + m_decoratorSize.width() + m_decoratorMargin * 2);
return result;
}
protected:
void paintEvent(QPaintEvent*) {
QPainter p(this);
QStyleOptionButton opt;
initStyleOption(&opt);
QStyleOptionButton subopt = opt;
subopt.rect = style()->subElementRect(QStyle::SE_CheckBoxIndicator, &opt, this);
style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &subopt, &p, this);
subopt.rect = style()->subElementRect(QStyle::SE_CheckBoxContents, &opt, this);
p.fillRect(QRect(subopt.rect.topLeft() + QPoint(m_decoratorMargin, 0),
m_decoratorSize), QBrush(Qt::green));
subopt.rect.translate(m_decoratorSize.width() + m_decoratorMargin * 2, 0);
style()->drawControl(QStyle::CE_CheckBoxLabel, &subopt, &p, this);
if (opt.state & QStyle::State_HasFocus) {
QStyleOptionFocusRect fropt;
fropt.rect = style()->subElementRect(QStyle::SE_CheckBoxFocusRect, &opt, this);
fropt.rect.setRight(fropt.rect.right() +
m_decoratorSize.width() + m_decoratorMargin * 2);
style()->drawPrimitive(QStyle::PE_FrameFocusRect, &fropt, &p, this);
}
}
private:
QSize m_decoratorSize;
int m_decoratorMargin;
};
请注意,此解决方案可能不可移植,因为在不同平台上绘制的复选框有很大差异。我只在 Windows 上测试过。我使用了提供的默认实现QCommonStyle
。