QListView item with checkbox selection behavior

Simon picture Simon · Jul 1, 2015 · Viewed 11k times · Source

I'm adding checkbox items to a list view.

Then when I change the check box indicator, the item row is not selected. And when I'm selection an item in the list, the check box indicator won't change.

The checkbox indicator should be selected/deselected on item selection row, and checkbox indicator selection should set the item row selected.

List view init:

QListView *poListView = new QListView(this);

// Create list view item model
QStandardItemModel*  poModel =
          new QStandardItemModel(poListView);

QStandardItem *poListItem = new QStandardItem;

// Checkable item
poListItem->setCheckable( true );

// Uncheck the item
poListItem->setCheckState(Qt::Unchecked);

// Save checke state
poListItem->setData(Qt::Unchecked, Qt::CheckStateRole);

poModel->setItem(0, poListItem);

poListView->setModel(poModel);

Any suggestion ?

Answer

Simon picture Simon · Jul 2, 2015

Solved this issue by connection two signals

  1. Registered model item changed signal for handling the checkbox indicator change.
  2. Registered view item activated signal for changing the checkbox indicator state

Here's my code:

void MyClass:Init() 
{
    m_poListView = new QListView(this);

    // Set single selection mode
    m_poListView->setSelectionMode(
               QAbstractItemView::SingleSelection);

    // Create list view item model
    QStandardItemModel*  poModel =
              new QStandardItemModel(m_poListView);

    QStandardItem * poListItem =
              new QStandardItem;

    // Checkable item
    poListItem->setCheckable( true );

    // Save checke state
    poListItem->setData(Qt::Unchecked, Qt::CheckStateRole);

    poModel->setItem(0, poListItem);

    m_poListView->setModel(poModel);

     // Register model item  changed signal
       connect(poModel, SIGNAL(itemChanged(QStandardItem*)),
       this,            SLOT  (SlotItemChanged(QStandardItem*)));

    // Resister view item acticated
     connect( m_poListView , SIGNAL(activated(const QModelIndex & )),
                 this,       SLOT(SlotListItemActivated(const QModelIndex & )))

}

Slots implemntation :

void MyClass::SlotItemChanged(QStandardItem *poItem)
{
    // Get current index from item
    const QModelIndex oCurrentIndex =
            poItemChanged->model()->indexFromItem(poItem);

    // Get list selection model
    QItemSelectionModel *poSelModel =
            m_poListView->selectionModel();

    // Set selection
    poSelModel->select(
                QItemSelection(oCurrentIndex, oCurrentIndex),
                QItemSelectionModel::Select | QItemSelectionModel::Current);
}

void MyClass::SlotListItemActivated(const QModelIndex &oIndex)
{
    Qt::CheckState eCheckState = Qt::Unchecked;

    // Get item's check state
    bool bChecked =
            oIndex.data(Qt::CheckStateRole).toBool();

    // Item checked ?
    if (bChecked == false) 
        eCheckState = Qt::Checked;
    else 
        eCheckState = Qt::Unchecked;

    // Get index model
      //    Note: I used QSortFilterProxyModel in the original code
    QSortFilterProxyModel *poModel = 
        (QSortFilterProxyModel *)oIndex.model();

    // Update model data
    poModel->setData(oIndex, eCheckState, Qt::CheckStateRole);
}