[Solved] Can't setData() of my QStandardItem selected via QItemSelectionModel::selectedIndexes



  • Hi,

    I have a "QTreeView":http://qt-project.org/doc/qt-4.8/qtreeview.html in my QMainWindow where I list QStandardItems with a QCheckbox. Now I want to be able to select these items and then via right-click check all the items that I selected with the mouse.
    I get the selected items via QTreeView->selectionModel()->selectedIndexes(). This QModelIndexList I then pass to my model which is derived from a QStandardItemModel. There I then go through the indexes and check via "QModelIndex::data(Qt::CheckStateRole)":http://qt-project.org/doc/qt-4.8/qstandarditemmodel.html#data if the item is checked or not (This works). If it is not I would like to set it via "QStandardItemModel::setData(QModelIndex,Qt::Checked,Qt::CheckStateRole)":http://qt-project.org/doc/qt-4.8/qstandarditemmodel.html#setData or by retrieving the QStandardItem via QStandardItemModel::itemFromIndex, both trials do not work.
    @void projectModel::extendSelection(QModelIndexList list)
    {
    QModelIndex i;
    disconnect(this,SIGNAL(itemChanged(QStandardItem *)),this,SLOT(submit()));
    foreach(i, list)
    {
    if(i.isValid())
    {
    if(i.data(Qt::CheckStateRole) == Qt::Checked)
    qDebug()<< "Index: " <<i.row() <<", " <<i.column() << "checked.";
    while((i.child(0,0).isValid()))
    {
    i = i.child(0,0);
    }
    if(i.column() == 0)
    {
    if(i.data(Qt::CheckStateRole) != Qt::Checked)
    {
    qDebug()<< "Index: " <<i.row() <<", " <<i.column() << "not checked yet.";
    //1.Trial
    if(!setData(i,Qt::Checked,Qt::CheckStateRole))
    {
    qDebug()<< "Setting CheckStateRole did not work!";
    }
    qDebug()<< "CheckStateRole of index is now: " <<i.data(Qt::CheckStateRole);

                     //2.Trial
                    QStandardItem* item = itemFromIndex(i);
                    if(item)
                        item->setCheckState(Qt::Checked);
                    else
                        qDebug()<< "item is invalid";
                }
                else
                {
                    qDebug()<< "Index: " <<i.row() <<", " <<i.column() << "already checked";
                }
    
            }
        }
    }
    submit();
    connect(this,SIGNAL(itemChanged(QStandardItem *)),this,SLOT(submit()));
    

    }
    @

    I guess, I have to map the index I got from the QItemSelectionModel to the data of my Model, but I don't know how to achieve this.

    I have been searching around of what I am doing wrong and tried several approaches, but nothing worked. So I hope any Qt expert can help me out.



  • Use
    @bool QStandardItemModel::setItemData(const QModelIndex & index, const QMap<int, QVariant> & roles);@



  • This does not change anything,
    since QStandardItemModel::setItemData is simply a convenience function which calls setData for each item in the roles map.



  • Have you also reimplemented setData of QStandardItemModel? If yes does it take care for role being QCheckStateRole?



  • No I did not reimplement setData in my Model, but am rather using QStandardItemModel::setData.
    It also works to set the QCheckSateRole in an other function of the Model as listed below, but here the QModelIndexList is not from a QItemSelectionModel of the view, but I iterate over a list retrieved by "QModelIndexList QAbstractItemModel::match":http://crpppc19.epfl.ch/doc/qt4-doc-html/html/qabstractitemmodel.html#match

    @void projectModel::changeSelection(QStandardItem currentItem, int itemCount, const QString &action)
    {
    if(currentItem==NULL) return;
    QModelIndex i;
    QString checkAction = action.trimmed().toLower();
    QList<QModelIndex> list = match(currentItem->index(), Qt::CheckStateRole, ".
    " /QString::number(Qt::Checked) + "|" + QString::number(Qt::PartiallyChecked) + "|" + QString::number(Qt::Unchecked)/, itemCount, Qt::MatchRegExp);
    foreach(i, list)
    {
    if(i.isValid())
    {
    if(i.child(0,0).isValid()) changeSelection(itemFromIndex(i.child(0,0)), itemFromIndex(i)->rowCount(),action);
    else if(i.column() == 0)
    {
    if(checkAction == "invert")
    {
    if(i.data(Qt::CheckStateRole) == Qt::Checked) setData(i,Qt::Unchecked,Qt::CheckStateRole);
    else if(i.data(Qt::CheckStateRole) == Qt::Unchecked) setData(i,Qt::Checked,Qt::CheckStateRole);
    }
    else if(checkAction == "selectall")
    {
    if(i.data(Qt::CheckStateRole) != Qt::Checked) setData(i,Qt::Checked,Qt::CheckStateRole);
    }
    @

    I still have the feeling it is the QModelIndexList that I get from QTreeView->selectionModel()->selectedIndexes(), that only lets me read the data via data() and not set the date via setData().



  • I found the problem and was able to solve it. Since I use a QSortFilterProxyModel on my QTreeView, the QModelIndex that I get from QTreeView->selectionModel()->selectedIndexes() is the ProxyIndex for the ProxyModel. So I had to get the index for the source model, which is done via
    @QModelIndex QSortFilterProxyModel::mapToSource(const QModelIndex & proxyIndex) @

    And then I have an Index that let's me edit the QStandardItem via QStandardItemModel::setData.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.