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

How to get the state of the QCheckbox on QTreeWidget while user clicks on it?



  • Hi,

    1. I have some one or more dynamic QCheckBox Widgets on the QTreeWidget
      2)I did add them to QTreeWidgetItem::setItemWidget() , Now while the user checks or unchecks I need to receive state and change the value according to the state in the corresponding iniSettings.
      3)How to do it?
      code:
    void Widget::createChild(QTreeWidgetItem &rootaddress,const QString &key,const QVariant &value)
    {
    bool checkItem=isCheckboxItem(rootaddress.text(0),key);
    if(checkItem)
    {
          QTreeWidgetItem *child=new QTreeWidgetItem;
          child->setText(0,key);
         QCheckBox *tempCheckbox=new QCheckBox;
         connect(tempCheckboc,SIGNAL(toggled(bool)),SLOT(check(bool)));//this is working, I have connected to local slot and I am 
         //gettings the true and false states from it, but can we able to get the parent and child QTreeWidgetItem of it?.
         child->setTextAlignment(0,Qt::AlignCenter);
         int val=value.toInt();
        if(val==1)
        {
          tempCheckbox->setChecked(true);
         }
       else
       {
         tempCheckbox->setChecked(false);
        }
    rootaddress.addchild(child);
    displayTreeWidget->setItemWidget(child,1,tempCheckbox);
    displayTreeWidget->itemWidget(child,1);
    }else{
      QTreeWidgetItem *child=new QTreeWidgetItem;
      child->setText(0,key);
      child->setTextAlignment(0,Qt::AlignCenter);
      child->setData(1,2,value);
      rootaddress.addChild(child);
    } 
    

    Ui link
    4) I need to get the toplevel QTreeWidgetItem name and sub QTreeWidgetItem name of corresponding QCheckBox, a user clicks.



  • @thippu
    In your checkItem == true route, I see a QTreeWidgetItem and a QCheckBox being created, but nowhere do I see them being added into the tree. Are we to presume you have such code but do not show it?

    Because I assume you find the QTreeWidgetItem by following the signalled QCheckBox's parent hierarchy, as necessary.

    P.S.
    If @VRonin sees this, I imagine he will be here like a bull in a china shop, cussing at you for trying to use QTreeWidgetItem::setItemWidget() and showing you how to do what you want via QStyledItemDelegate, in which case your problem might go away....



  • In your checkItem == true route, I see a QTreeWidgetItem and a QCheckBox being created, but nowhere do I see them being added into the tree. Are we to presume you have such code but do not show it?

    Hi,
    That is typo mistake, I have a development server, which is restricted from using the internet and copying through a pen drive or etc, So I can't able to do copy and paste. I'm asking apologizes from u.



  • @JonB using this approach cannot able to achieve solve this problem?



  • @JonB said in How to get the state of the QCheckbox on QTreeWidget while user clicks on it?:

    Because I assume you find the QTreeWidgetItem by following the signalled QCheckBox's parent hierarchy, as necessary.

    I don't know still how to find it. I need help to find it.



  • @thippu said in How to get the state of the QCheckbox on QTreeWidget while user clicks on it?:

    I did add them to QTreeWidgetItem::setItemWidget()

    As a rule of thumb, setItemWidget() should not be used unless you have a very strong and thought reason (see my signature for my stance on this method).

    This is a typical case where setItemWidget() is not just useless but also more complicated to use than the native solution.

    To have a checkbox in a QTreeWidgetItem you just need to call widgetItem->setData(column, Qt::CheckStateRole, Qt::Unchecked);. If you want the user to be able to check/uncheck the box, use widgetItem->setFlags(widgetItem->flags() | Qt::ItemIsUserCheckable);

    To detect changes to the items checked/unchecked you can use:

    connect(treeWidget->model(),&QAbstractItemModel::dataChanged,[](const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles){
    if(!roles.contains(Qt::CheckStateRole)) return;
    // the checkboxes between topLeft and bottomRight changed
    // usually topLeft == bottomRight 
    // you can use topLeft.parent() to get the item 1 step higher in the hierarchy
    }
    


  • @VRonin Thank you bro.



  • I had an idea to solve this, what I did is:
    1)Created QVector<QCheckbox*>checkbox and populated references in it and QSetting paths with the group, the key in another QVector<QString> in below function:

    void Widget::createChild(QTreeWidgetItem &rootaddress,const QString &key,const QVariant &value)
    {
    bool checkItem=isCheckboxItem(rootaddress.text(0),key);
    if(checkItem)
    {
    QTreeWidgetItem *child=new QTreeWidgetItem;
    child->setText(0,key);
    QCheckBox *tempCheckbox=new QCheckBox;
    connect(tempCheckboc,SIGNAL(toggled(bool)),SLOT(check(bool)));//this is working, I have connected to local slot and I am
    //gettings the true and false states from it, but can we able to get the parent and child QTreeWidgetItem of it?.
    child->setTextAlignment(0,Qt::AlignCenter);
    int val=value.toInt();
    if(val==1)
    {
    tempCheckbox->setChecked(true);
    }
    else
    {
    tempCheckbox->setChecked(false);
    }
    rootaddress.addchild(child);
    displayTreeWidget->setItemWidget(child,1,tempCheckbox);
    displayTreeWidget->itemWidget(child,1);
    }else{
    QTreeWidgetItem *child=new QTreeWidgetItem;
    child->setText(0,key);
    child->setTextAlignment(0,Qt::AlignCenter);
    child->setData(1,2,value);
    rootaddress.addChild(child);
    }

    1. In the slot I did
    void Widget::check(bool state)
    {
     if(state)
    {
    QCheckBox *p=static_cast<QCheckBox *>(QObject::sender());
    int index=checkbox_refs->indexOf(p);
    QString temppath=checkbox_paths->value(index);
    QVariant value=1;
    iniSettings->setValue(temppath,value.toString());
    iniSettings->sync();
    }
    else
    {
    QCheckBox *p=static_cast<QCheckBox *>(QObject::sender());
    int index=checkbox_refs->indexOf(p);
    QString temppath=checkbox_paths->value(index);
    QVariant value=1;
    iniSettings->setValue(temppath,value.toString());
    iniSettings->sync();
    }
    }
    

    It works but one issue is there:

    1)it correctly updates the value on the key of QSettings::objectbut
    2)also adds groupname\keyname=value after it. why and how to solve this.
    Ui
    output


Log in to reply