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复选框渲染的部分代码:

cpp 复制代码
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.功能接口举例

cpp 复制代码
    //设置对齐方式
    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渲染部分代码示例

cpp 复制代码
    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扩展组件类,后面会封装成插件动态库,感兴趣的同学可以留言哦

相关推荐
lansye3 小时前
侃侃AI编程
开发语言·qt·ai编程
uyeonashi4 小时前
【QT】窗口详解
开发语言·c++·qt·学习
追风赶月、10 小时前
【QT】控件一(QWidget、Button、Label)
开发语言·qt
十秒耿直拆包选手12 小时前
Qt:Qt桌面程序正常退出注意事项
c++·qt
姆路12 小时前
Qt背景平铺
开发语言·qt
范纹杉想快点毕业13 小时前
初探Qt信号与槽机制
java·c语言·开发语言·c++·qt·visualstudio·visual studio
uyeonashi1 天前
【QT系统相关】QT文件
开发语言·c++·qt·学习
Wyn_1 天前
【QT】QTableView自定义样式:仅显示行间隔、隐藏列间隔、表头样式、表格样式、单行选中等
qt·qtableview
٩( 'ω' )و2601 天前
qt信号与槽--01
开发语言·qt
傻傻虎虎1 天前
【QT】自动更新库QSimpleUpdater使用实例封装
开发语言·qt