2
votes

QTreeWidget is not working as expected when clicking on check-box of non-leaf item. My QTreeWidget has two level of child and each item in the tree widget can be checked (check-box is enabled for each item). In this QTreeWidget, leaf items are user selectable, but non-leaf items are not selectable and all items are enabled and user check-able.

[]Family node1
  - []Primary node1
    - []child1
  - []Secondary node1
    - []child1
[]Family node2
  - []Primary node2
    - []child2
  - []Secondary node2
    - []child2

Leaf items flag setting

Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled

Non-leaf items flag setting

Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsTristate

When we directly click on leaf item's associated check-box, Qt is generating currentItemChanged() signal. But, when we click directly on non-leaf item's associated check-box, then currentItemChanged() signal is not getting generated. This causes inconvenience in the non-leaf item handling.

It was working fine in Qt 4.7.4, but it is not working in Qt 4.8.1 on all platforms (Windows, Darwin, and Linux).

I attached a sample program to reproduce this bug.

Is this a bug or expected behavior?

I am noticing this bug on all platforms (Linux CentOS, Windows 7, and MacOS) with Qt 4.8.

1
I created a Qt bug report QTBUG-27567 for this issue and you can download the sample program from the Qt bug report page QTBUG-27567.vipin jain
+1 for the detailed question and the complete, compilable and runnable sample! I just tried it on MS Windows/MingW with Qt 4.8.2, and I observe the following: handleCurrentItemChanged() is called ONLY when the TEXT of the tree node is clicked. This is consistent with the change of the selection: only then the selected node is visualized selected afterwards. Whenever I click on the checkbox itself (leaf OR non-leaf), handleCurrentItemChanged() is NOT called. For me it looks like this is correct behaviour (maybe also a difference between 4.8.1 and 4.8.2). The question is: what do you expect?Andreas Fester
I updated my comment in QTBUG-27567 with detail information why we are getting different behavior in Qt 4.8 compare to Qt 4.7. This change is introduced by QTBUG-4435. I expect that current item should be set to clicked item.vipin jain
Despite the question whether this is a regression in Qt: Would something like item->treeWidget()->clearSelection(); item->setSelected(true); in handleItemClicked() help?Andreas Fester
We also do not want to change the selection when user directly click on check-box. so, above would not work well.vipin jain

1 Answers

0
votes

Maybe you're looking for something like this:

//widget.h:
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
class QTreeWidgetItem;

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
private slots:
    void slotTest(QTreeWidgetItem *ite,int idx);
private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

//widget.cpp:
#include "widget.h"
#include "ui_widget.h"

#include <QtGui>

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

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->treeWidget->setColumnCount(1);
    QList<QTreeWidgetItem *> items;
    QTreeWidgetItem * item;
     for (int i = 0; i < 10; ++i)
     {
         item = new QTreeWidgetItem((QTreeWidget*)0, QStringList(QString("item: %1").arg(i)));
         item->setCheckState(0,i%2 == 0 ? Qt::Unchecked : Qt::Checked);
         items.append(item);
     }
     connect(ui->treeWidget,SIGNAL(itemClicked(QTreeWidgetItem*,int)),this,SLOT(slotTest(QTreeWidgetItem*,int)));
     ui->treeWidget->insertTopLevelItems(0, items);
}


void Widget::slotTest(QTreeWidgetItem *ite,int idx)
{
    if(ite)
    {
        qDebug() << ite->text(0);
    }
}

//widget.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>274</width>
    <height>210</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Widget</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <widget class="QTreeWidget" name="treeWidget">
     <column>
      <property name="text">
       <string notr="true">1</string>
      </property>
     </column>
    </widget>
   </item>
  </layout>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>