Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QTreeView/QAbstractItemModel : signal "dataChanged" does not update item flags
Forum Updated to NodeBB v4.3 + New Features

QTreeView/QAbstractItemModel : signal "dataChanged" does not update item flags

Scheduled Pinned Locked Moved General and Desktop
4 Posts 1 Posters 10.3k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Mario84
    wrote on last edited by
    #1

    Hello everybody,

    I am working on a QTreeView that display five columns of Checkboxes (Policies in a Usermanagement) and those checkboxes are displayed as icons, set via a style sheet.
    Which icon is displayed depends on two values:

    1. the Data of the item (QAbstractItemModel::data())
    2. the Flags of the item (QAbstractItemModel::flags())

    When the user clicks on one of those checkboxes, it is possible (because of a hierarchical policy-system) that not only the item clicked, but also several other items change their state. (unchecked, checked-normal, checked-grayed/inherited)
    To do so, in QAbstractItemModel::setData() I change the data in the TreeItem-Class and then emit dataChanged() for the related items.

    The problem is that the items only aplly the changes it gets through the method data(), which is not enough to display the correct icon. The flags() are also needed, but this method does not seem to be called by the view after dataChanged is emitted. So I can see that the icons change (= my Model-Indices are correct) but they aren't displayed as they should. I have to expand/collapse any Treenode, to cause the view to update correctly (after this second action, everything is displayed as it is supposed to be)

    So my question is:
    Is there a way to tell the view to update the flags of specific items, from inside the model(without actually knowing the view)?

    P.S.:
    I already thougt about misusing Qt::PartiallyChecked which would enable me to completely avoid the problem by not using flags(), but I'd prefer to use my version, because this workaround is only suitable for three states, and in the future there might come a fourth state...

    Here's some code-snippets from my prototype:
    @QVariant CCheckBoxModel::data(const QModelIndex &index, int role) const
    {
    QVariant result;

    if (!index.isValid() || index.column() == 6)
    {
    return result;
    }

    TreeItem item = static_cast<TreeItem>(index.internalPointer());

    if ((role == Qt::CheckStateRole) && (index.column() != 0))
    {
    result = item->data(index.column());

    return result;
    }

    if ((role != Qt::DisplayRole) || (index.column() != 0))
    {
    return QVariant();
    }

    result = item->data(index.column());

    return result;
    }

    Qt::ItemFlags CCheckBoxModel::flags(const QModelIndex &index) const
    {
    if (!index.isValid())
    {
    return NULL;
    }

    TreeItem item = static_cast<TreeItem>(index.internalPointer());

    if (index.column() == 0)
    {
    return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    }
    else //CheckBoxes
    {
    if (item->isInherited(index.column()))
    {
    return Qt::ItemIsSelectable;
    }
    else
    {
    return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEditable;
    }
    }
    }

    bool CCheckBoxModel::setData(const QModelIndex &index, const QVariant &value, int role)
    {
    if (!index.isValid() || index.column() == 6)
    {
    return true;
    }

    TreeItem item = static_cast<TreeItem>(index.internalPointer());

    if ((role == Qt::CheckStateRole) && (index.column() != 0))
    {
    item->setData(index.column(), value);
    emit dataChanged(index, this->index(item->childCount(), index.column(), index)); //the children might have changed too
    }

    return true;
    }@

    1 Reply Last reply
    0
    • M Offline
      M Offline
      Mario84
      wrote on last edited by
      #2

      Update:
      The flags()-method does not seem to be the problem, the changes of the flags are applied immediately (at least the enabled state...). The problem is the style sheet:
      The style sheet seems to be applied after a call to data() but before the call to flags(); at least that's what I assume after analyzing the behaviour. Or in other words: the enabled/disabled state is updated after the style sheet, which is wrong (in my case).
      So I'd need a way to apply the style sheet after updating the items state.

      Here's my style sheet, set for the QTreeView:
      @QAbstractItemView::indicator:enabled:checked
      {
      image: url(:cbChecked);
      }

      QAbstractItemView::indicator:enabled:unchecked
      {
      image: url(:cbUnchecked);
      }

      QAbstractItemView::indicator:disabled:checked
      {
      image: url(:cbGray);
      }

      //QAbstractItemView::indicator:disabled:unchecked is not used@

      btw: resetting the style with treeview->setStyleSheet(treeview->styleSheet()) in a slot connected to dataChanged() does not work

      1 Reply Last reply
      0
      • M Offline
        M Offline
        Mario84
        wrote on last edited by
        #3

        Next update ;)

        My style sheet theory is not correct, wen I disable the style sheet completely and use the standard checkboxes, the problem is the same: enabled/disabled is "functionally" updated but not visually...

        1 Reply Last reply
        0
        • M Offline
          M Offline
          Mario84
          wrote on last edited by
          #4

          Ok, I solved it by not using real checkboxes at all, now I'm just returning the correct checkbox-icon in data() and nothing for CheckStateRole. I had to connect the clicked-signal from the view with an own slot in my model which implements the checkbox-behaviour...

          If somebody has a better idea, Id appreciate to hear it ;)
          But for now this problem is solved...

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved