It is all in how you write the code.
Make a method that auto. (un)checks your child boxes like so:
void ConfigurationForm
::checkGroupChildren(QTreeWidgetItem* pItem,
enum Qt
::CheckState eCheckState
) {
if (pItem)
{
int nChildCount = pItem->childCount();
for (int i = 0; i < nChildCount; i++)
{
pItem->child(i)->setCheckState(0,eCheckState);
}
checkSiblingsSetParent(pItem); // If it is a child, set the parent check state accordingly
}
}
void ConfigurationForm::checkGroupChildren(QTreeWidgetItem* pItem, enum Qt::CheckState eCheckState)
{
if (pItem)
{
int nChildCount = pItem->childCount();
for (int i = 0; i < nChildCount; i++)
{
pItem->child(i)->setCheckState(0,eCheckState);
}
checkSiblingsSetParent(pItem); // If it is a child, set the parent check state accordingly
}
}
To copy to clipboard, switch view to plain text mode
The next thing you need to do is send the right signal... itemClicked().
connect(ui.treewMode, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(modeItemChecked(QTreeWidgetItem*,int)));
To copy to clipboard, switch view to plain text mode
To get this to work as intended you need to write modeItemChecked() like this:
void ConfigurationForm
::modeItemChecked(QTreeWidgetItem* pItem,
int nColumn
) {
if (pItem != NULL && nColumn != -1)
{
enum Qt::CheckState eCheckState = pItem->checkState(0);
checkGroupChildren(pItem, eCheckState); // Check Items Children
}
}
void ConfigurationForm::modeItemChecked(QTreeWidgetItem* pItem, int nColumn )
{
if (pItem != NULL && nColumn != -1)
{
enum Qt::CheckState eCheckState = pItem->checkState(0);
checkGroupChildren(pItem, eCheckState); // Check Items Children
}
}
To copy to clipboard, switch view to plain text mode
So the theory is that when ever you click the text of the item... it will call this method. In that case it will not matter... nothing will change unless your children are not of the same check state. That is the main draw back of this design... it is not that bad though. When you do (un)check the check box... it will pick it up and (un)check the children. This is a lot easier solution than the one give above... especially if you are using Qt Designer.
Hope that helps.
EDITED:
I also had to add this function:
{
enum Qt::CheckState eCheckState = Qt::Unchecked;
if (pItem != NULL) // Is a valid Item
{
pParentItem = pItem->parent();
if (pParentItem != NULL) // Item was a child
{
int nChildCount = pParentItem->childCount();
for (int i = 0; i < nChildCount; i++)
{
// See if any siblings are checked
if (pParentItem->child(i)->checkState(0) == Qt::Checked)
{
eCheckState = Qt::Checked;
break;
}
}
pParentItem->setCheckState(0, eCheckState); // Set parent according to children status
}
}
}
void ConfigurationForm::checkSiblingsSetParent(QTreeWidgetItem* pItem)
{
QTreeWidgetItem* pParentItem = NULL;
enum Qt::CheckState eCheckState = Qt::Unchecked;
if (pItem != NULL) // Is a valid Item
{
pParentItem = pItem->parent();
if (pParentItem != NULL) // Item was a child
{
int nChildCount = pParentItem->childCount();
for (int i = 0; i < nChildCount; i++)
{
// See if any siblings are checked
if (pParentItem->child(i)->checkState(0) == Qt::Checked)
{
eCheckState = Qt::Checked;
break;
}
}
pParentItem->setCheckState(0, eCheckState); // Set parent according to children status
}
}
}
To copy to clipboard, switch view to plain text mode
This way... when you (un)check a child box... the parent will reflect the correct change. I modified my original post code to use this function. It has been tested and works great.
Bookmarks