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

时间:2015-07-01 14:00:07

标签: qt qlistview qstandarditem

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

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

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

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

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

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

  1. 已注册的模型项已更改信号,用于处理复选框指示符更改。
  2. 已注册的查看项目已激活信号,用于更改复选框指示符状态
  3. 这是我的代码:

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

答案 1 :(得分:0)

您必须连接itemChanged的{​​{1}}信号并在那里手动选择项目。

如果您希望选中复选框,则还必须连接QStandardItemModel的{​​{1}}信号,然后选中/取消选中项目。

此外,您不需要手动设置selectionChanged

使用C ++ 11和lambdas,如下所示:

QListView::selectionModel()

或使用旧的Qt::CheckStageRole语法:

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