Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Can a top level item have a checkbox?



  • I'm trying to create a TreeView that looks like this where there is a checkbox in the top level items.

    [] Item1
        ItemA
        ItemB
    [] Item2 
        ItemA
        ItemB
    [] Item3
        ItemA
        ItemB
    

    Yet, I'm not seeing what I expect. Checkboxes appear for ItemA and itemB of Item1 only. When I dynamically create my tree, here is how I add items to the tree ...

    The TreeModel is initialized as:

    QVector<QVariant> rootData;
    rootData << "Col1" << "Col2";
    
    parentItem = new MyTreeItem(rootData);
    
    model = new MyTreeModel(parentItem);
    

    And items are add by user like:

    // ...
    QCheckBox *cb = new QCheckBox;
    cb->setCheckState(Qt::Checked);
    
    QVector<QVariant> data;
    QVector<QVariant> data1;
    QVector<QVariant> data2;
    
    data << name << QVariant::fromValue(cb);
    data1 << a1_name; // <-- just qstring names
    data2 << a2_name;
                                                                               
    MyTreeItem *item = new MyTreeItem(data, parentItem);
    item->setLabel(itemName);
    
    parentItem->appendChild(item);
    
    MyTreeItem *item1 = new MyTreeItem(data1, item);
    item1->setLabel(itemName1);
    
    item->appendChild(item1);
    
    MyTreeItem *item2 = new MyTreeItem(data2, item);
    item2->setLabel(itemName2);
    
    item->appendChild(item2);
    

    And here's the flags() of the TreeModel.

    Qt::ItemFlags MyTreeModel::flags(const QModelIndex &index) const
    {   
        if (!index.isValid())
            return 0;
    
        Qt::ItemFlags flags;
    
        if (index.column() <= 1) {
            
            flags = Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
        }
    
         return flags;
     }
    

    Any thoughts as to why this isn't drawing the tree I'm looking for?



  • Hi SRad,
    I am not sure that can solve your problem but I think flags method should be like that.

    Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
    {
        if (!index.isValid())
            return 0;
    
        Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
        if (index.column() == 0 && !index.parent().isValid()) {
            flags |=  Qt::ItemIsUserCheckable;
            return flags;
        }
    
        return  QAbstractItemModel::flags(index);;
    }
    

    And also you should imlement data and setData mehtods like below

    QVariant TreeModel::data(const QModelIndex &index, int role) const
    {
        if (!index.isValid())
            return QVariant();
    
       TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
       if ( role == Qt::CheckStateRole && index.column() == 0 && !index.parent().isValid() )
            return static_cast< int >( item->isChecked() ? Qt::Checked : Qt::Unchecked );
    
        if (role != Qt::DisplayRole)
            return QVariant();
    
    
        return item->data(index.column());
    }
    //! [3]
    bool TreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
    {
    
        TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
        if(role == Qt::CheckStateRole)
        {
    
                    if(item->isChecked())
                        item->setChecked(false);
                    else
                        item->setChecked(true);
                    emit dataChanged(index, index);
                    return true;
        }
    
        if (role != Qt::EditRole)
            return false;
    
    
        return QAbstractItemModel::setData(index,value,role);
    }
    
    

    Result
    Capture.PNG
    If you can show your MyTreeItem content, I can help much.



  • Hi SRad,
    I am not sure that can solve your problem but I think flags method should be like that.

    Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
    {
        if (!index.isValid())
            return 0;
    
        Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
        if (index.column() == 0 && !index.parent().isValid()) {
            flags |=  Qt::ItemIsUserCheckable;
            return flags;
        }
    
        return  QAbstractItemModel::flags(index);;
    }
    

    And also you should imlement data and setData mehtods like below

    QVariant TreeModel::data(const QModelIndex &index, int role) const
    {
        if (!index.isValid())
            return QVariant();
    
       TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
       if ( role == Qt::CheckStateRole && index.column() == 0 && !index.parent().isValid() )
            return static_cast< int >( item->isChecked() ? Qt::Checked : Qt::Unchecked );
    
        if (role != Qt::DisplayRole)
            return QVariant();
    
    
        return item->data(index.column());
    }
    //! [3]
    bool TreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
    {
    
        TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
        if(role == Qt::CheckStateRole)
        {
    
                    if(item->isChecked())
                        item->setChecked(false);
                    else
                        item->setChecked(true);
                    emit dataChanged(index, index);
                    return true;
        }
    
        if (role != Qt::EditRole)
            return false;
    
    
        return QAbstractItemModel::setData(index,value,role);
    }
    
    

    Result
    Capture.PNG
    If you can show your MyTreeItem content, I can help much.



  • @CKurdu - Thanks for the help, this worked out great.



  • @SRaD
    You are welcome. Good luck.


Log in to reply