设为首页 加入收藏

TOP

【VS Code 与 Qt6】QCheckBox的图标为什么不会切换?(一)
2023-07-23 13:29:20 】 浏览:101
Tags:Code Qt6 QCheckBox

本篇专门扯一下有关 QCheckBox 组件的一个问题。老周不水字数,直接上程序,你看了就明白。

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QCheckBox>
#include <QVBoxLayout>
#include <QIcon>

int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    // 最平庸的窗口
    QWidget window;
    window.setWindowTitle("看看这是?");
    window.setGeometry(/*坐标*/600, 450, /*大小*/280, 170);
    // 布局
    QVBoxLayout *layout = new QVBoxLayout;
    window.setLayout(layout);
    // 控件列表
    QCheckBox *cb = new QCheckBox(&window);
    cb -> setText("看,左边的图标不会变");
    layout -> addWidget(cb);
    QPushButton *btn = new QPushButton(&window);
    btn->setText("看,左边的图标会变");
    // 让按钮支持check操作
    btn->setCheckable(true);
    layout->addWidget(btn);
    // 图标
    QIcon icon;
    // 第一个图,当checked的时候显示
    icon.addFile("1.png", QSize(), QIcon::Normal, QIcon::On);
    // 第二个图,当unchecked的时候显示
    icon.addFile("2.png", QSize(), QIcon::Normal, QIcon::Off);
    // 应用图标
    cb->setIcon(icon);
    btn->setIcon(icon);
    
    // 显示窗口
    window.show();

    return QApplication::exec();
}

QCheckBox、QRadioButton、QPushButton 都是 QAbstractButton 的子类,所以这几个家伙都归属于按钮组件。在 QAbstractButton 类中已定义有 checkable 属性,表示按钮是否支持 check 操作。这种按钮就类似于现实世界中的自锁按钮——按一下【开】,再按一下【关】。而普通的按钮是无状态记忆的,按下去+弹起来为一个周期,称为 Click。

由于是派生关系,所以 QCheckBox 和 QPushButton 类都会继承 check 功能的支持,只是 QCheckBox 默认是打开这项功能的。QPushButton 类默认不能 check,所以得调用 setCheckable 方法手动打开功能。

   btn->setCheckable(true);

下面重点扯扯 QIcon 这货,看名识义,你能猜到它表示的是图标。QIcon 类可以根据不同状态添加多个图标。老周这个例子是添加了两个 PNG 图标。懒得生成什么鬼 Qrc 资源了,直接把图片文件复制到程序可执行文件所在的目录就完事了。比如,build/Debug,只要和可执行文件在同一个目录就行,方便相对路径引用。

    QIcon icon;
    // 第一个图,当checked的时候显示
    icon.addFile("1.png", QSize(), QIcon::Normal, QIcon::On);
    // 第二个图,当unchecked的时候显示
    icon.addFile("2.png", QSize(), QIcon::Normal, QIcon::Off);

这里涉及到 QIcon 类定义的两枚举:

A、Mode:

1)Normal —— 组件的正常状态;

2)Disbaled —— 被禁用,比如按钮不能点击;

3)Active —— 其实和 Normal 差不多,只是多了一条:正在与用户交互。比如活动窗口,获得焦点的按钮,获得焦点的输入框等;

4)Selected —— 这个有些奇葩,一般在子项对象起作用。比如,ListView 视图的子项被选中时。

B、State:

1)On —— 状态“开”。比如 CheckBox 处于 checked 状态;

2)Off —— 状态“关”。如 CheckBox 的 Unchecked 状态。

回到咱们的代码。这两个图标的区别就在 State 的值不同,当 On 时显示 1.png;当状态为 Off 时显示 2.png。

    icon.addFile("1.png", QSize(), QIcon::Normal, QIcon::On);
    icon.addFile("2.png", QSize(), QIcon::Normal, QIcon::Off);

addFile 的第一个参数是文件路径,第二个参数指定图标的大小,这里用 QSize 类的默认构造函数,即宽和高都是 -1,这样图标会根据样式获取默认大小。

运行程序,咱们测试下。如下图所示,这是初始状态,上下两个组件都没有 check。

然后,咱们依次点击它们,让这两个组件都处于 checked 状态。

咱们看到:QPushButton 切换状态后图标也跟着变了,但是 QCheckBox 一点动静都没有。这 NM 是怎么回事?

原来,QPushButton 的默认样式中,在获取图标时,会根据 checked 状态来提取 On 或 Off 相关的图标。

 case CE_PushButtonLabel:
        if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
            ……

            if (!button->icon.isNull()) {
                //Center both icon and text
                QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
                if (mode == QIcon::Normal && button->state & State_HasFocus)
                    mode = QIcon::Active;
                QIcon::State state = QIcon::Off;                 if (button->state & State_On)
                    state = QIcon::On;

                ……
        break;

再看看 QCheckBox 的样式,发现这厮在获取图标时是不考虑 On 或 Off 状态的。

    case CE_RadioButtonLabel:
    case CE_CheckBoxLabel:
        ……
            if (!btn->icon.isNull()) {
                pix = btn->icon.pixmap(btn-
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇刨析一下C++构造析构函数能不能声.. 下一篇驱动开发:内核解析PE结构节表

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目