如何在QCheckBox中的文本和复选框之间绘制一个正方形
How to draw a Square between the text and the checkbox in QCheckBox
我需要像这样自定义 QCheckbox
:在复选框和文本之间添加一个正方形 :
所以为了做到这一点,我继承了 QCheckBox
并覆盖了 paintEvent(QPaintEvent*)
:
void customCheckBox::paintEvent(QPaintEvent*){
QPainter p(this);
QStyleOptionButton opt;
initStyleOption(&opt);
style()->drawControl(QStyle::CE_CheckBox,&opt,&p,this);
QFontMetrics font= this->fontMetrics();// try to get pos by bounding rect of text, but it ain't work :p
QRectF rec = font.boundingRect(this->text());
p.fillRect(rect,QBrush(QColor(125,125,125,128)));
p.drawRect(rect);
}
我有一个问题,我不知道如何放置 QRectF rec
。而且我不能将尺寸设置得太小,例如:当尺寸 rec
< QSize(10,10).
时它会消失
欢迎任何想法。
PS:我使用 OpenSUSE 13.1 和 Qt 4.8.5
主要思想是复制复选框绘图的默认实现并根据您的需要进行修改。我们在默认实现中得到了标签矩形,所以我们只需要在这个地方绘制新元素并将标签向右移动。我们还需要调整大小提示,以便新元素和默认内容都适合最小尺寸。
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
.
提供的默认实现
QAbstractButton
有一个属性叫做icon
,根据实例化的子类不同画法不同
幸运的是,图标在 QCheckBox
中的位置与您在图片中所示的位置完全相同。
因此,您需要为自定义的 QCheckBox
做的就是定义图标应该是什么,默认的 paintEvent
会处理其余的。
为简单起见,我假设图标大小应与复选框本身大小相同:
class CheckBox : public QCheckBox {
public:
CheckBox() {
QStyleOptionButton option;
initStyleOption(&option);
QSize indicatorSize = style()->proxy()->subElementRect(QStyle::SE_CheckBoxIndicator, &option, this).size();
QPixmap pixmap(indicatorSize);
pixmap.fill(Qt::green);
QIcon icon;
icon.addPixmap(pixmap);
setIcon(icon);
}
};
我已经在装有 Qt 5.2.1 的 Windows 8.1 机器上测试过了,它可以工作。
我需要像这样自定义 QCheckbox
:在复选框和文本之间添加一个正方形
所以为了做到这一点,我继承了 QCheckBox
并覆盖了 paintEvent(QPaintEvent*)
:
void customCheckBox::paintEvent(QPaintEvent*){
QPainter p(this);
QStyleOptionButton opt;
initStyleOption(&opt);
style()->drawControl(QStyle::CE_CheckBox,&opt,&p,this);
QFontMetrics font= this->fontMetrics();// try to get pos by bounding rect of text, but it ain't work :p
QRectF rec = font.boundingRect(this->text());
p.fillRect(rect,QBrush(QColor(125,125,125,128)));
p.drawRect(rect);
}
我有一个问题,我不知道如何放置 QRectF rec
。而且我不能将尺寸设置得太小,例如:当尺寸 rec
< QSize(10,10).
欢迎任何想法。
PS:我使用 OpenSUSE 13.1 和 Qt 4.8.5
主要思想是复制复选框绘图的默认实现并根据您的需要进行修改。我们在默认实现中得到了标签矩形,所以我们只需要在这个地方绘制新元素并将标签向右移动。我们还需要调整大小提示,以便新元素和默认内容都适合最小尺寸。
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
.
QAbstractButton
有一个属性叫做icon
,根据实例化的子类不同画法不同
幸运的是,图标在 QCheckBox
中的位置与您在图片中所示的位置完全相同。
因此,您需要为自定义的 QCheckBox
做的就是定义图标应该是什么,默认的 paintEvent
会处理其余的。
为简单起见,我假设图标大小应与复选框本身大小相同:
class CheckBox : public QCheckBox {
public:
CheckBox() {
QStyleOptionButton option;
initStyleOption(&option);
QSize indicatorSize = style()->proxy()->subElementRect(QStyle::SE_CheckBoxIndicator, &option, this).size();
QPixmap pixmap(indicatorSize);
pixmap.fill(Qt::green);
QIcon icon;
icon.addPixmap(pixmap);
setIcon(icon);
}
};
我已经在装有 Qt 5.2.1 的 Windows 8.1 机器上测试过了,它可以工作。