05 扩展组件:自定义CheckBox组件

系列文章目录

01 Qt自定义风格控件的基本原则-CSDN博客

02 从QLabel聊起:自定义控件扩展-图片控件-CSDN博客 

 03 从QLabel聊起:自定义控件扩展-文本控件-CSDN博客

04 自定义Button组件:令人抓狂的QToolButton文本图标居中问题-CSDN博客 


目录

系列文章目录

前言

一、从QCheckBox渲染源码说起

1.QCheckBox渲染源码

2.源码简述

二、自定义Button控件的使用场景

1.风格示意图

三、 实现思路 

1.概述

2.功能接口举例

3.CheckBox渲染部分代码示例

 4.注意事项

总结


前言

在篇幅《04 自定义Button组件:令人抓狂的QToolButton文本图标居中问题》中我根据QToolButton源码简单陈述了:为什么我们在业务开发场景中,同时居中按钮文本、图标复杂的原因。 其根本原因就在于Qt源码中已经把文本元素与图标元素的间隙设为固定值4个像素!

很遗憾的是, QCheckBox复选框控件类依旧存在以下让我不舒服的固定风格:

  • 图标与文本间距依旧固定值4个像素
  • 图标、文本对齐方式固定为水平居左、垂直居中

所以, 今天想分享的是自己在自定义CheckBox组件上的思路与方法!

既聊思路,也说代码!我们开始今天的CheckBox扩展控件类的分享!


一、从QCheckBox渲染源码说起

1.QCheckBox渲染源码

以下为Qt源码中关于QCheckBox复选框渲染的部分代码:

uint alignment = visualAlignment(btn->direction, Qt::AlignLeft | Qt::AlignVCenter);

if (!proxy()->styleHint(SH_UnderlineShortcut, btn, widget))
        alignment |= Qt::TextHideMnemonic;
QPixmap pix;
QRect textRect = btn->rect;
if (!btn->icon.isNull()) {
       pix = btn->icon.pixmap(qt_getWindow(widget), btn->iconSize, btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled);
proxy()->drawItemPixmap(p, btn->rect, alignment, pix);
if (btn->direction == Qt::RightToLeft)
       textRect.setRight(textRect.right() - btn->iconSize.width() - 4);
 else
      textRect.setLeft(textRect.left() + btn->iconSize.width() + 4);
 }
 if (!btn->text.isEmpty())
{
   proxy()->drawItemText(p, textRect, alignment | Qt::TextShowMnemonic,
            btn->palette, btn->state & State_Enabled, btn->text,         
  QPalette::WindowText);
 }

详情见qcommonstyle.cpp中函数:QCommonStyle::drawControl

2.源码简述

从上述源码可以得知:

首先,在第一行源码中固定了图标、文本的对齐方式为 Qt::AlignLeft | Qt::AlignVCenter;

其次,文本矩形区域textRect 显然以图标矩形的右边为基准且偏移4个像素。

二、自定义CheckBox控件的使用场景

1.风格示意图

示意图2-1

三、 实现思路 

1.概述

为了沿用QCheckBox的基本功能接口, 我们需要继承QCheckBox类, 然后在paintEvent中实时绘制图标与文本内容, 必要的话还要区分三态效果(包括:checked  unchecked partialChecked)

2.功能接口举例

    //设置对齐方式
    void setAlignment(Qt::Alignment align);
    //图标、文本间距
    void setSpacing(int spacing);
    //设置文本字号
    void setButtonTextSize(int pixSize);
    //设置三态图标
    void setButtonIcon(const QString& checked, const QString& unchecked, const QString& partiallyChecked);
    //设置按钮文本颜色
    void setButtonTextColor(const QColor& clr);

3.CheckBox渲染部分代码示例

    QStylePainter paint(this);
    //背景透明
    paint.fillRect(rect(), Qt::transparent);
    //渲染图标+文本要素 
    QRect rcDisplay = styledRect();
    QRect rcPix = rcDisplay;
    QRect rcText = rcDisplay;
    rcPix.setWidth(iconSize().width());//左上角不变,缩小宽度
    rcText.adjust(rcPix.width() + m_iSpacing, 0, 0, 0);//
    //绘制图标
    QPixmap pix = styledIcon().pixmap(qt_getWindow(this), rcDisplay.size().boundedTo(iconSize()));
    paint.drawItemPixmap(rcPix, Qt::AlignCenter, pix);
    //绘制文本
    paint.setFont(font());
    paint.setPen(styledTextColor());
    paint.drawText(rcText, Qt::AlignCenter, text());

 4.注意事项

这里有一点要提醒大伙儿注意, 如果我们通过自绘制改变了文本、图标渲染的位置, 那么CheckBox的点击事件也相应要做处理!(比如:我们的图标绘制在左上角,用户点击右下角是不是应该不响应该次操作呢?)

好在, QCheckBox也给我们预留了虚函数:QCheckBox::hitButton。

必要时,要重写这个虚函数的!


 

总结

OK,以上就是今天想和大家分享的内容,本篇主要针对QCheckBox类做些功能扩展,然后独立出一个自定义的组件CheckBox。

既聊思路,也说代码!我们下次继续分享自定义风格扩展组件!

PS:本专栏所有篇幅涉及的UI扩展组件类,后面会封装成插件动态库,感兴趣的同学可以留言哦

  • 20
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

峭桑岱司

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值