【问题标题】:How to draw a Square between the text and the checkbox in QCheckBox如何在 QCheckBox 中的文本和复选框之间绘制一个正方形
【发布时间】:2015-05-30 18:37:54
【问题描述】:

我需要像这样自定义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

感谢任何想法。

PS:我使用 OpenSUSE 13.1 和 Qt 4.8.5

【问题讨论】:

    标签: qt qwidget qcheckbox


    【解决方案1】:

    主要思想是复制复选框绘制的默认实现并根据您的需要进行修改。我们在默认实现中得到标签矩形,所以我们只需要在这个地方绘制新元素并将标签向右移动。我们还需要调整尺寸提示,使新元素和默认内容都适合最小尺寸。

    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提供的默认实现。

    【讨论】:

    • 您好,您的解决方案部分有效:它确实在复选框和文本之间创建了矩形;但文字减半。我的猜测是我们需要重新计算文本的边界?怎么做?
    • 好吧,我傻了。我只需要在 GUI 上调整它的大小。
    【解决方案2】:

    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 机器上对此进行了测试,它可以工作。

    【讨论】:

    • 您好,您的解决方案部分有效:它确实在复选框和文本之间创建了矩形;但文字减半。我的猜测是我们需要重新计算文本的boundingrect
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多