带有复选框选择行为的QListView项

问题描述 投票:0回答:2

我正在将复选框项添加到列表视图中。

然后,当我更改复选框指示符时,未选中项目行。当我在列表中选择一个项目时,复选框指示符不会改变。

应在项目选择行上选中/取消选中复选框指示符,并且复选框指示符选择应设置所选项目行。

列表视图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);

有什么建议吗?

qt qlistview qstandarditem
2个回答
1
投票

通过连接两个信号解决了这个问题

  1. 已注册的模型项已更改信号以处理复选框指示符更改。
  2. 注册视图项激活信号,用于更改复选框指示器状态

这是我的代码:

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 & )))

}

插槽实现:

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);
}

0
投票

你必须连接itemChangedQStandardItemModel信号并在那里手动选择项目。

如果你想在选择时选中复选框,你还必须连接selectionChangedQListView::selectionModel()信号并检查/取消选中那里的项目。

此外,您不需要手动设置Qt::CheckStageRole

使用C ++ 11和lambdas看起来像这样:

connect(poModel, &QStandardItemModel::itemChanged, [poListView, poModel](QStandardItem * item) {
    const QModelIndex index = poModel->indexFromItem(item);
    QItemSelectionModel *selModel = poListView->selectionModel();
    selModel->select(QItemSelection(index, index), item->checkState() == Qt::Checked ? QItemSelectionModel::Select : QItemSelectionModel::Deselect);
});

connect(poListView->selectionModel(), &QItemSelectionModel::selectionChanged, [poModel](const QItemSelection &selected, const QItemSelection &deselected) {
    for (const QModelIndex &index : selected.indexes()) {
        poModel->itemFromIndex(index)->setCheckState(Qt::Checked);
    }
    for (const QModelIndex &index : deselected.indexes()) {
        poModel->itemFromIndex(index)->setCheckState(Qt::Unchecked);
    }
});

或者使用旧的connect语法:

void MyClass::handleCheckedChanged(QStandardItem *item) {
    const QModelIndex index = item->model()->indexFromItem(item);
    QItemSelectionModel *selModel = poListView->selectionModel();
    selModel->select(QItemSelection(index, index), item->checkState() == Qt::Checked ? QItemSelectionModel::Select : QItemSelectionModel::Deselect);
}

void MyClass::handleSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) {
    foreach (const QModelIndex &index, selected.indexes()) {
        index.model()->itemFromIndex(index)->setCheckState(Qt::Checked);
    }
    foreach (const QModelIndex &index, deselected.indexes()) {
        index.model()->itemFromIndex(index)->setCheckState(Qt::Unchecked);
    }
}

...

connect(poModel, SIGNAL(itemChanged(QStandardItem *)), this, SLOT(handleCheckedChanged(QStandardItem *)));

connect(poListView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(handleSelectionChanged(QItemSelection, QItemSelection)));
© www.soinside.com 2019 - 2024. All rights reserved.