Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Accessing ui.TableViewCells from the data_source
-
I really do have a brain freeze on this issue. For the life of me I can't remember how to recover a reference to a ui.TableViewCell lets say when the row is selected. I did search the forum but i could not see an answer. In the below code, I create the cells up front. But I have a feeling this is bad. I remember omz does some tricky things with tablecells so they can be re-used to save memory.
In my example below, I just want to toggle a checkmark on the selected row. I don't want to use ui.ListDataSource, because this is just the simple version I want to do.Sorry in advance because I think the answer is going to be very simple.
Any help appreciatedimport ui class MyDataSource(object): def __init__(self, data): ''' I cant remember how to get access to a ui.TableViewCell, so i created the cells and store them in a list. I have a feeling this is bad. There must be a simple way to get the cell by index. Brain Hurts! ''' self.data = data self.sel_item = 0 self.cells = [ui.TableViewCell() for _ in range(len(self.data))] def tableview_number_of_rows(self, tableview, section): # Return the number of rows in the section return len(self.data) def tableview_cell_for_row(self, tableview, section, row): # Create and return a cell for the given section/row cell = self.cells[row] cell.text_label.text = self.data[row] return cell def tableview_did_select(self, tableview, section, row): # Called when a row was selected. self.select_row(row) pass def tableview_did_deselect(self, tableview, section, row): # Called when a row was de-selected (in multiple selection mode). pass def select_row(self, sel_row): for cell in self.cells: cell.accessory_type = "" self.cells[sel_row].accessory_type = 'checkmark' self.sel_item = sel_row def get_table(items): tbl = ui.TableView(frame=(0, 0, 300, 400)) tbl.data_source = MyDataSource(items) tbl.delegate = tbl.data_source return tbl if __name__ == '__main__': v = get_table(['Ian', 'Fred', 'John', 'Paul']) v.present(style='sheet', animated=False)
-
I think part of the concept is mvc where your datasource doesn't need access to the cell (presentation layer) itself -- instead cellforrow produces the cell looking the way you want, and you reload if you want to change it.
in practice, what you've got seems reasonable.
-
@JonB , thanks for the answer. I was finding it hard to believe I had not had this problem before. But it sort of makes sense as I rarely finish anything to a full working something that does anything useful or complete.
@omz, could you weigh in regards if this approach is ok. Look, for what I am doing at the moment i am at max going to needs around 10 rows. But is there a point where this approach could or start to fail because you start to re-use ui.TableViewCells?
I would like to know. I see myself doing a lot more with ui.TableView. I personally think being to update the cell after creation is important. Eg from an web request etc..... Not all can be known at creation time. Anyway interested in what you think the right approach is -
@Phuket2 If you just have 10 cells or so, it's totally fine to initialize them all at once. That's exactly what
dialogs.form_dialog()
is doing btw. This can become a problem if you have hundreds of cells, but that's typically not the case in a settings-style UI. -
@omz , ok thanks for the info.
-
Oh, btw. I might have even seen this before. Sometimes its a blur for me if I have worked something out for the first time, or if I have seen it before. I have looked at dialogs before, but it was a long time ago. Good chance i would not have understood what it was doing anyway. But I think its a good idea to go and re-look with fresh eyes and mind. Learn some new things