Qt-interest Archive, April 2008
Qt::ItemIsTristate - No Qt::PartiallyChecked in setData(...)
Message 1 in thread
I'm trying to add Tristate checkbox functionality to an existing
QTreeView that uses my own model. The problem is that I don't get
Qt::PartiallyChecked values from the model's setData(...) method. The
only values I get for Qt::CheckStateRole are Qt::Unchecked and
Qt::Checked. How do you get Qt::PartiallyChecked values from
setData(...)?
The flags that are set for my checkable items are as follows:
Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate |
Qt::ItemIsSelectable
Any ideas as to how I can get Qt::PartiallyChecked values from
QAbstractItemModel::setData(...)?
Thanks.
Qt 4.4 Snapshot: 4.4.0-snapshot-20080229
Mac OS X 10.5.2
--
[ signature omitted ]
Message 2 in thread
On Thursday 03 April 2008 01:56:05 Dave Thorup wrote:
> Any ideas as to how I can get Qt::PartiallyChecked values from
> QAbstractItemModel::setData(...)?
Hi,
In your model you need to return values asscociated with the
Qt::CheckStateRole. Just return the checkStateof the items in question. This
does support the partially checked state. e.g.:
if ( index.column() == 0 && role == Qt::CheckStateRole )
{
StructureModelNode* item = static_cast<StructureModelNode*>(
index.internalPointer() );
return item->checkState();
}
HTH,
Sean
--
[ signature omitted ]
Message 3 in thread
On Apr 3, 2008, at 4:01 AM, Sean Harmer wrote:
> On Thursday 03 April 2008 01:56:05 Dave Thorup wrote:
>> Any ideas as to how I can get Qt::PartiallyChecked values from
>> QAbstractItemModel::setData(...)?
> Hi,
>
> In your model you need to return values asscociated with the
> Qt::CheckStateRole. Just return the checkStateof the items in
> question. This
> does support the partially checked state. e.g.:
I'm not having any problems displaying checkboxes using the
Qt::PartiallyChecked state (which does not require the
Qt::ItemIsTristate flag). The problem is that in calls to
QAbstractItemModel::setData(...) the values that are passed by
setData(...) are only Qt::Unchecked and Qt::Checked,
Qt::PartiallyChecked is never passed to setData(...) and thus I can
never set the data in my model to Qt::PartiallyChecked.
This is in stark contrast to how QCheckBoxes work. If you set a
checkbox to be Tristate ( setTristate( true ) ), then the checkbox
will cycle between the three states when you click on it. The same
should also be true for an ItemView when its model returns the
"Qt::ItemIsUserCheckable | Qt::ItemIsTristate" flags for a given
item. Apparently this is not the case, you only get two states in an
ItemView - Qt::Unchecked and Qt::Checked - even if you use the flag
Qt::ItemIsTristate.
--
[ signature omitted ]
Message 4 in thread
Dave Thorup wrote:
> I'm not having any problems displaying checkboxes using the
> Qt::PartiallyChecked state (which does not require the
> Qt::ItemIsTristate flag). The problem is that in calls to
> QAbstractItemModel::setData(...) the values that are passed by
> setData(...) are only Qt::Unchecked and Qt::Checked,
> Qt::PartiallyChecked is never passed to setData(...) and thus I can
> never set the data in my model to Qt::PartiallyChecked.
Ah OK sorry I misunderstood the problem. What we have done in the past
is to only use the partially checked state when a subset of the children
of a parent item are checked and the rest are unchecked/partially
checked. To do this you have to recurse up the hierarchy of items when
setData() is called on a child to change the check state.
We also implemented it in the other direction. That is, when the parent
is checked or unchecked we recurse down through its children and check
or uncheck them respectively.
> This is in stark contrast to how QCheckBoxes work. If you set a
> checkbox to be Tristate ( setTristate( true ) ), then the checkbox
> will cycle between the three states when you click on it. The same
> should also be true for an ItemView when its model returns the
> "Qt::ItemIsUserCheckable | Qt::ItemIsTristate" flags for a given
> item. Apparently this is not the case, you only get two states in an
> ItemView - Qt::Unchecked and Qt::Checked - even if you use the flag
> Qt::ItemIsTristate.
I don't know that what you are after here is possible. But I could well
be wrong.
Cheers,
Sean
--
[ signature omitted ]
Message 5 in thread
On Apr 3, 2008, at 3:01 PM, Sean Harmer wrote:
> Dave Thorup wrote:
>> I'm not having any problems displaying checkboxes using the
>> Qt::PartiallyChecked state (which does not require the
>> Qt::ItemIsTristate flag). The problem is that in calls to
>> QAbstractItemModel::setData(...) the values that are passed by
>> setData(...) are only Qt::Unchecked and Qt::Checked,
>> Qt::PartiallyChecked is never passed to setData(...) and thus I can
>> never set the data in my model to Qt::PartiallyChecked.
> Ah OK sorry I misunderstood the problem. What we have done in the
> past is to only use the partially checked state when a subset of the
> children of a parent item are checked and the rest are unchecked/
> partially checked. To do this you have to recurse up the hierarchy
> of items when setData() is called on a child to change the check
> state.
>
> We also implemented it in the other direction. That is, when the
> parent is checked or unchecked we recurse down through its children
> and check or uncheck them respectively.
This is what I've been doing as well and it's been working well.
However, I wanted to add the ability for the user to cycle between
Checked, Unchecked & Partially Checked when the default state of a
parent has some of its children checked. i.e. Only when clicking on
a parent item that has children would the user be allowed to set the
Partially Checked state. In that case when going from all children
unchecked to the partially checked state, the children's check state
would be set to their default state and the parent item would display
Partially Checked (if some of the children's default states are
unchecked).
>
>> This is in stark contrast to how QCheckBoxes work. If you set a
>> checkbox to be Tristate ( setTristate( true ) ), then the checkbox
>> will cycle between the three states when you click on it. The same
>> should also be true for an ItemView when its model returns the
>> "Qt::ItemIsUserCheckable | Qt::ItemIsTristate" flags for a given
>> item. Apparently this is not the case, you only get two states in
>> an ItemView - Qt::Unchecked and Qt::Checked - even if you use the
>> flag Qt::ItemIsTristate.
> I don't know that what you are after here is possible. But I could
> well be wrong.
I found the solution and apparently this is a bug that for whatever
reason won't be fixed:
http://trolltech.com/developer/task-tracker/index_html?method=entry&id=108755
Apparently you have to create your own QItemDelegate for your item
view in order to get the correct behavior. I don't understand how
they can dismiss this as something that they won't fix since it
doesn't even work in the way they describe in the bug report:
After returning the Qt::ItemIsTristate flag from
QAbstractTableModel::flags(....) , the supplied checkboxs do not
possess tristate functionality.
Won't fix:
The intended usage of Qt::ItemIsTristate is to signify that the
checked state of an item should be computed as a function of the
checked states of its child items; e.g. no child items checked =>
parent becomes unchecked; some child items checked => parent is
partially checked; all child items checked => parent item checked.
Therefore, the default item delegate does not have provisions for
interactive partial checking of items. However, you can reimplement
QItemDelegate::editorEvent() and change the behavior to what you want,
for example like this:
The "intended usage" that they describe is not how Item Views actually
work. If you have an Item View and your own Model then it's up to you
to return the proper check state regardless of whether you set the
Qt::ItemIsTristate flag. For example, if you have a parent where some
of it's children are checked and some are not and you use the
Qt::ItemIsTristate flag then the parent's check state will not
magically be set to partially checked, it will be set to whatever your
model returns - checked, unchecked or partially check - which is as it
should be. The Qt::ItemIsTristate shouldn't magically override how
your model works, it should allow the default QItemDelegate to send
the 3 check states to your model's setData(...) method just as
QCheckBox::setTristate( true) works. I don't understand how this
can't be seen as a bug.
--
[ signature omitted ]