frmdstryr / enamlx

Additional Qt Widgets for Enaml
MIT License
28 stars 9 forks source link

Deletion expose lifecycle problem #16

Open Annakan opened 5 years ago

Annakan commented 5 years ago
  1. Open the default TableView example or my example at : https://github.com/Annakan/EnamlxTableView_warts/tree/master/table_view1 (it is the same without the extra thread adding stuff and messing with the data)

  2. Go to the end of the table

  3. Click "remove person"

=>

Projects/EnamlxTableView/table_view1/table_view.enaml", line 116, in <module>
    attr person << table.items[self.row]
IndexError: list index out of range

That probably means that the "refresh induced by subscription" happens and start to iterate on the iterable << range(table.visible_rows) while visible_rows is still set to a wrong (+1) value. I noticed this happening a lot in many different situations. for instance in table_view.enaml from https://github.com/Annakan/EnamlxTableView_warts/tree/master/table_view4

   Looper:looper:
        iterable << model.people[table.visible_row:min(table.visible_row+table.visible_rows, len(model.people))]
        TableViewRow:                    
            ###########################################################################
            # This works in the most ugly of ways
            attr person << loop_item
            # and we need to protect ourselves because index can overstep  its bounds
            row <<  model.people.index(person)  if person in model.people else -99999999
           ###########################################################################

Try to remove ff person in model.people else -99999999 on the last line and boom, even though in that example I am looping on the items themselves like this iterable << model.people[table.visible_row:min(table.visible_row+table.visible_rows, len(model.people))]

So either visible_rows is not updated after deletion or not early enough ... I don't know :)

If we do row << model.people.index(person) if person in model.people else -99999999 to avoid the IndexError and do other guarding on the rest of the row preparation then one can see a "blanck" row at the bottom of the grid, some pause and then the TableView refreshing itself, this time properly (even without forcing refresh from the remove button with table.looper.refresh_items())