Как нарисовать квадрат между текстом и флажком в 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);
}
У меня есть проблема, что я не знаю, как место, чтобы разместить Любые идеи приветствуются. PS: я использую OpenSUSE 13.1 с Qt 4.8.5QRectF rec
, И я не могу установить слишком маленький размер, например: он исчезнет, когда размер rec
2 ответа
Основная идея заключается в том, чтобы скопировать реализацию по умолчанию для рисования флажков и изменить ее в соответствии с вашими потребностями. Мы получаем прямоугольник метки в реализации по умолчанию, поэтому нам просто нужно нарисовать новый элемент в этом месте и сместить метку вправо. Также нам нужно настроить подсказку по размеру, чтобы новый элемент и содержимое по умолчанию соответствовали минимальному размеру.
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);
}
};
Я проверил это на компьютере с Windows 8.1 с Qt 5.2.1, и он работает.