如何在文本和QCheckBox

时间:2015-05-30 18:37:55

标签: qt qwidget qcheckbox

我需要像这样自定义QCheckbox:在复选框和文字Example之间添加一个正方形:

为此,我继承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< echo的尺寸时它将消失。 QSIZE(10,10)。

任何想法都表示赞赏。

PS:我使用OpenSUSE 13.1和Qt 4.8.5

2 个答案:

答案 0 :(得分: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提供的默认实现。

答案 1 :(得分:1)

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计算机上对此进行了测试,并且可以正常运行。