QStandardItem通过setCheckable添加复选框后无法再次通过setCheckable取消复选框的问题

前言

如题所示,通过setCheckable添加复选框后,想要通过setCheckable(false)取消复选框,你会发现根本没有作用的。

问题复现

#include "widget.h"
#include "ui_widget.h"
#include 

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    m_model = new QStandardItemModel(this);
    m_model->setHorizontalHeaderLabels(QStringList() << QStringLiteral("班级/名称") << QStringLiteral("性别") << QStringLiteral("学号"));
    QStandardItem *class_1 = new QStandardItem(QStringLiteral("班级1"));
    QStandardItem *st1_name = new QStandardItem(QStringLiteral("小明"));
    //这个item添加复选框
    st1_name->setCheckable(true);
    QStandardItem *st1_sex = new QStandardItem(QStringLiteral("男"));
    QStandardItem *st1_number = new QStandardItem(QStringLiteral("1"));

    QStandardItem *st2_name = new QStandardItem(QStringLiteral("老王"));
    st2_name->setCheckable(true);
    QStandardItem *st2_sex = new QStandardItem(QStringLiteral("男"));
    QStandardItem *st2_number = new QStandardItem(QStringLiteral("2"));
    class_1->appendRow(QList<QStandardItem*>() << st1_name << st1_sex << st1_number);
    class_1->appendRow(QList<QStandardItem*>() << st2_name << st2_sex << st2_number);

    QStandardItem *class_2 = new QStandardItem(QStringLiteral("班级2"));
    QStandardItem *st3_name = new QStandardItem(QStringLiteral("小翠"));
    st3_name->setCheckable(true);
    QStandardItem *st3_sex = new QStandardItem(QStringLiteral("女"));
    QStandardItem *st3_number = new QStandardItem(QStringLiteral("3"));

    QStandardItem *st4_name = new QStandardItem(QStringLiteral("小红"));
    st4_name->setCheckable(true);
    QStandardItem *st4_sex = new QStandardItem(QStringLiteral("女"));
    QStandardItem *st4_number = new QStandardItem(QStringLiteral("4"));

    class_2->appendRow(QList<QStandardItem*>() << st3_name << st3_sex << st3_number);
    class_2->appendRow(QList<QStandardItem*>() << st4_name << st4_sex << st4_number);

    m_model->appendRow(class_1);
    m_model->appendRow(class_2);
    ui->treeView->setModel(m_model);
}

Widget::~Widget()
{
    delete ui;
}

效果如下
QStandardItem通过setCheckable添加复选框后无法再次通过setCheckable取消复选框的问题_第1张图片

通过 setCheckable(false) 取消复选框的设置

void Widget::on_pushButton_clicked()
{
    QStandardItem *item = m_model->item(0, 0)->child(0, 0);
    qDebug() << item->text();
    item->setCheckable(false);
}
经过测试发现根本没有效果。

正确的姿势

void Widget::on_pushButton_clicked()
{
    QStandardItem *item = m_model->item(0, 0)->child(0, 0);
    qDebug() << item->text();
    item->setData(QVariant(), Qt::CheckStateRole);
}

通过源码我们可以看到 setCheckable(true)是进行了如下操作

/*!
  Sets whether the item is user-checkable. If \a checkable is true, the
  item can be checked by the user; otherwise, the user cannot check
  the item.

  The item delegate will render a checkable item with a check box next to the
  item's text.

  \sa isCheckable(), setCheckState(), setUserTristate(), setAutoTristate()
*/
void QStandardItem::setCheckable(bool checkable)
{
    Q_D(QStandardItem);
    if (checkable && !isCheckable()) {
        // make sure there's data for the checkstate role
        if (!data(Qt::CheckStateRole).isValid())
            setData(Qt::Unchecked, Qt::CheckStateRole);
    }
    d->changeFlags(checkable, Qt::ItemIsUserCheckable);
}

可以看见实际上使用setCheckable(true)最后也是调用了setData(Qt::Unchecked, Qt::CheckStateRole)函数而已。

你可能感兴趣的:(我的QT,qt)