[SOLVED] Tablemodel dataChanged problem

  • Hi,

    I have treeview and a tableview neatly linked together. When a parent node in the treeview expands it shows nicely corresponding table rows with group permissions for each service in the treeview.


    1) if I click on the checkbox of a parent cell child cells should take the same value

    2) if I click on the checkbox of a child cell the checkbox of the parent cell should update itself according to values of the child checkboxes. If all are checkbox the parent is checked, if none are checked the parent is unchecked, in other cases it is partially checked

    This all works when I do either 1 or 2. But together there are interactions. Changing the data of one checkbox leads to emitting of other "data changed" signals. How to avoid this? I tried temporary blocksignals. But in that case other checkboxes don't update.

    @QStandardItemModel *m_tableModel
    QStandardItemModel *m_treeviewModel;

    connect(m_tableModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(setCheckBoxes(QModelIndex,QModelIndex)));

    void groupPermissions::setCheckBoxes(QModelIndex indexA, QModelIndex indexB)

    void groupPermissions::toggleCheckBoxes(QModelIndex tableIndex)
    QStandardItem *treeviewItem;
    treeviewItem = m_treeviewModel->itemFromIndex(getTreeviewIndex(tableIndex));

    // either of these if's works properly alone, but together they create a mess
    if (treeviewItem->rowCount() != 0 ) setChildCheckBoxes(tableIndex); 
    if (treeviewItem->rowCount() == 0) setParentCheckBox(tableIndex);


  • The screenshot can't be seen, also not from the link you provided: access denied.

    You cannot and should not avoid that from happening. Why do you want to stop it from happening? Anyway, it sounds like you are trying to re-implement "CheckableProxyModel":/wiki/QSortFilterProxyModel_subclass_to_add_a_checkbox ...

  • The link I just repaired. I was not aware of CheckableProxyModel. I will check it out.

  • [quote author="Zarkon" date="1400054490"]The link I just repaired.[/quote]

    Quote: no, you did not. It still says 403 access denied. Problem is: you probably can't see that, as you do have access. I usually use dropbox to host images I want to put on the forum...

  • Dropbox is not allowed in this company. I have use my own site. And also there I had to implement a lot of security because it is under constant attack by zombies. Second try. I hope it shows because I dont think CheckableProxyModel is the answer.

  • [quote]403 - Permission Denied

    You been messing around and that was noticed, <my ip> has been banned.[/quote]

    If clicking a link to a picture you posted is "messing around", your security measures may be a bit too strict..

    Is imgbin.org allowed for you?

  • Used my photo album site now. It should be ok. For safety better remove your ip-address.

  • It seems like a rather complicated setup. Why are you using two views, instead of one? I would have simply added a couple of columns to my tree view model and not worry about any syncing between models...

    Anyway, the picture is more clear now. I think you do need something like what CheckableProxyModel does, but not exactly. Where this proxy model only keeps track of one checked state per row in the source model, you need to keep track of five that you put in different columns. Your benefit: you don't have a deep hierarchy.

    I still don't get what the actual problem is you are trying to solve? As I asked before:
    [quote author="Andre" date="1400054152"]You cannot and should not avoid that from happening. Why do you want to stop it from happening? [/quote]

    Are you seeing recursive calls to your update code perhaps?

  • The recursive calls are the problem.

    The thing is when I set the parent row to checked it sets the children to checked (1). So far fine. But the children generate also a "data changed" event. They update the parent when procedure (2) is enabled. This kinds of locks both the parent and the children.

    Also if I check the children one by one (2-repeatedly) the parent updates nicely (gets checked when all children are checked). However combined with (1) the children cannot be set to checked or when unchecked, uncheck all children.

  • It is a matter of making sure that you only emit the data changed event if you actually set new data. Or, if you use QStandardItemModel, only set a state if the state really is different from the previous state. You can of course also block your handling of the recursive calls using a simple flag or something like that.

    I basically had the same problem when writing CheckableProxyModel. I used a more complicated solution there. The solution I implemented was something along these lines: Instead of having three states (Checked, Unchecked, Partial), you have four (Checked, Unchecked, DeterminedByParent, DeterminedByChildren). The DeteriminedBy... states evaluate to checked or unchecked or partial, depending on the state of items.

    For leaf items, the default value is DeterminedByParent. If an item gets and explicit state, it's siblings will also get an explicit state (that of the parent), and the parent goes to DeterminedByChildren. I think I had a process that in the background simplified the tree when possible (make sure that if all children of a parent have the same state, they all get the DeterminedByParent state again and the parent gets the explicit state instead).

    As I was working with having to keep track of the checked state separately from the data itself, and the tree would potentially be huge and not even completely loaded (like with QFileSystemModel), that worked to keep a small and efficient data structure.

  • I put the whole procedure now in the on click event of the tableview. That creates some overhead when you click beside the checkbox (state does not change), but looping is now prevented.

Log in to reply

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