PDA

View Full Version : ItemIsUserCheckable and checking all selected items



edice
28th May 2009, 07:26
Hi,

I have a subclassed QAbstractListModel attached to a QListView. I have setSelectionMode(ExtendedSelection)

I would like to be able to select multiple rows, and then press the spacebar, and have it toggle the checkboxes on ALL of the selected rows.

How can I make this happen?

I was thinking of a hack in my model::setData() ... give the model the list's selectionModel so that it knows what other items are selected, and then the setData() method can do the work of toggling all the checks. But this seems to go against the class design...

thanks,
Paul

wysota
28th May 2009, 07:46
Eeeem... no, that's a bad way of doing things :)

Reimplement keyPressEvent for the view and inside iterate over the selection model of the view and call setData for each item with appropriate role and value.

edice
28th May 2009, 07:53
How do I do that if the form has been designed in designer? Its a QListView...

wysota
28th May 2009, 08:12
Right click on it and choose "Promote to" and enter your subclass data. Alternatively you can install an event filter on the view instead of reimplementing it.

edice
28th May 2009, 10:43
Excellent, thanks for that tip.

I went with the eventFilter method, see below... I had to tell the event filter about the model, and the model has a toggle(QModelIndex) method which does the tick/unticking.

The alternative was to call ListView::edit(idx), but that didn't work, or the protected edit(idx,trigger,event), but I thought that was too much to fudge, at least this way I know what code is going to be executed.




class MultiTicker : public QObject
{
public:
MultiTicker(QAbstractItemView * view, ListModel_Checkable * model) : QObject(view), view(view), model(model) {}

protected:
bool eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = dynamic_cast<QKeyEvent*>(event);
switch (keyEvent->key())
{
case Qt::Key_Space:
case Qt::Key_Enter:
case Qt::Key_Return:
case Qt::Key_Select: // I think this a Phone/PDA key, but never mind hopefully can't hurt
{
// get the current selection
QModelIndexList sels = view->selectionModel()->selectedIndexes();
// get the current index
QModelIndex curr = view->currentIndex();

// are we a member?
if (sels.contains(curr))
{
// for each selection, toggle the checkbox through
// the usual listview::edit method.
for (QModelIndexList::iterator s = sels.begin(); s != sels.end(); ++s)
model->toggle(*s);
return true;
}
}

default: ;
}
}
// standard event processing
return QObject::eventFilter(obj, event);
}

private:
QAbstractItemView * view;
ListModel_Checkable * model;
};

wysota
28th May 2009, 13:14
What do you mean about the edit() thing? You don't need to touch edit in any way. You just call setData() with Qt::CheckStateRole on the model for each index and that's it.