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.
Strategy for TableViews with sections
-
I'm working on this right now. My understanding is that the trick is making the right data source class as
ListDataSource
isn't made for multi section data. There is an example in the docs for this that I'm trying to work with, but for some reason my code is not working. I've been able to make a hard coded list that has multiple sections, but I'm trying to make a class to which I can feed a dictionary of the type shown in the code below and have it populate a tableview. Any ideas?# coding: utf-8 import ui class MyTableViewDataSource (object): def tableview_number_of_sections(self, tableview): # Return the number of sections (defaults to 1) return 0 def tableview_number_of_rows(self, tableview, section): # Return the number of rows in the section #print section return 0 def tableview_cell_for_row(self, tableview, section, row): # Create and return a cell for the given section/row cell = ui.TableViewCell() print 'cell name: ', row cell.text_label.text = row return cell def tableview_title_for_header(self, tableview, section): # Return a title for the given section. # If this is not implemented, no section headers will be shown. print 'section: ', section return section def tableview_can_delete(self, tableview, section, row): # Return True if the user should be able to delete the given row. return False def tableview_can_move(self, tableview, section, row): # Return True if a reordering control should be shown for the given row (in editing mode). return False def fill_data(self, tableview, data): for section in data: self.tableview_title_for_header(tableview, section) for row in data[section]: self.tableview_cell_for_row(tableview, section, row) multi_section = ui.TableView() multi_section.width = 400 multi_section.height = 400 list = {'Header1': ['element1', 'element2', 'element3'], 'Header2': ['element3', 'element4', 'element5'], 'Header3': ['element6', 'element7', 'element8'], 'Header4': ['element9', 'element10']} data = MyTableViewDataSource() multi_section.data_source = data data.fill_data(multi_section, list) multi_section.present('sheet')
-
Instead of calling the tableview delegate methods yourself, your class needs to use tableview.data to properly fill out those methods when called by the system. For instance
def tableview_number_of_sections(self,tableview): return len(tableview.data.keys()) def tableview_title_for_header(self,tableview,section): return tableview.data.keys()[section] def tableview_number_of_rows(self,tableview,section): key = tableview.data.keys()[section] return len(tableview.data[key])
and so on. the system will call these methods for you, and set up your tableview based on what is returned. Look at the source for ListDataSource in ui.py for more info.
I vaguely recall that section and row might be one based rather than zero based, so you kight need to use section-1 in the code above for indexing. I don't have the app open right now to check, but it should be easy to add a print to see.
-
@JonB, Thanks for the help. I admit I still don't totally understand how this is works. I haven't been able to find the source code for the ui module. Below is my working code. As with most of my code, I'm sure there's many ways to improve it. I had to change to using an
OrderedDict
so the order of elements would be preserved.import ui from collections import OrderedDict class MyTableViewDataSource (object): def tableview_number_of_sections(self,tableview): return len(self.data.keys()) def tableview_title_for_header(self,tableview,section): return self.data.keys()[section] def tableview_number_of_rows(self,tableview,section): key = self.data.keys()[section] return len(self.data[key]) def tableview_cell_for_row(self, tableview, section, row): # Create and return a cell for the given section/row key = self.data.keys()[section] cell = ui.TableViewCell() cell.text_label.text = self.data[key][row] return cell def fill_data(self, tableview, data): self.data = data multi_section = ui.TableView() multi_section.width = 400 multi_section.height = 400 table = OrderedDict([('Header1', ['element1', 'element2', 'element3']), ('Header2', ['element3', 'element4', 'element5']), ('Header3', ['element6', 'element7', 'element8']), ('Header4', ['element9', 'element10'])]) data = MyTableViewDataSource() multi_section.data_source = data data.fill_data(multi_section, table) multi_section.present('sheet')
-
You can enable Standard Library view in settings, then if you go to Standard Library-> site-packages, the pythonista module sources are there (see ui.py)
-
@smath list is probably not the best variable name for your ordered dict... The code above overrides the definition of a builtin type.
print(list((0, 1, 2))) # works list = 'a b c'.split() print(list((0, 1, 2))) # throws an exception
-
-
This simple thing still drives me crazy. I am sure it's just me and my lack of experience. But as it turns out, I have been looking at this again the last few days. Then I seen this old question I asked before started getting some feedback.
Actually the feedback is very nice.
But unrelated to this threat, I was looking at iOS development , in Flipboard (which I never do). And I come across this article.
http://nshipster.com/uisplitviewcontroller/uisplitviewcontroller, sounds super cool in name alone. After reading , seems like it would be perfect addition to the ui suite.
I really have no idea how deep objc_utils can go in creating native objects and incorporating them into Pythonista , but this would be a fantastic addition.
Whist, it seems that it should be so easy to create a split view of your own , it is. But then, you start to implement stuff, all of a sudden it can get complicated and ugly. Granted, skill helps a lot here. But I find I am always painting my self into a corner. But I do have a lack of skill.Anyway, maybe some of you guys ofay with objc_utils could help add this as a customview. Just asking 😛😛😛
-
I spent a while implementing somethng very much like this for an improved version of gitview... essentially trying to emulate the little side panels that pop out in pythonista for the file view, etc, then you can swipe to dismiss. This was all in standard puthonista ui.
Sadly, I lost all of my in work work when switching to the new version, because I tried to get fancy (I thought I could just share the files to email, then just save a draft, and would be able to open it again.... but that didnt work unbeknownst to me, and i lost weeks of work when ai uninstalled).
-
A slightly different formulation that implements an
__init__()
method in place offill_data()
so you canmulti_section.data_source = MyTableViewDataSource(data_dict)
in a single line of code.import ui from collections import OrderedDict class MyTableViewDataSource (object): def __init__(self, data_dict=None): self.data = data_dict def section_key(self, section): return self.data.keys()[section] def tableview_number_of_sections(self, tableview): return len(self.data) def tableview_title_for_header(self, tableview, section): return self.section_key(section) def tableview_number_of_rows(self, tableview, section): return len(self.data[self.section_key(section)]) def tableview_cell_for_row(self, tableview, section, row): # Create and return a cell for the given section/row cell = ui.TableViewCell() cell.text_label.text = self.data[self.section_key(section)][row] return cell multi_section = ui.TableView() multi_section.width = multi_section.height = 400 data_dict = OrderedDict((('Header1', ('element0', 'element1', 'element2')), ('Header2', ('element3', 'element4', 'element5')), ('Header3', ('element6', 'element7', 'element8')), ('Header4', ('element9', 'element10')))) multi_section.data_source = MyTableViewDataSource(data_dict) multi_section.present('sheet')
-
@JonB , that's a bummer. So many Real world ui"s are based around this simple master detail concept on iPhones and iPads. I mentioned before in another thread, I have really been over thinking the whole ui thing. Just need to get a solid master detail class in place, then a few tweaks from there, such as status bars etc.
but I was looking how to handle section data all wrong also. After seeing it in this thread, it appears more obvious. I think the TableView is one of those ui elements that deserve a lot more documentation.
But it's great to see the buzz around the version 2.0 release. It's got a lot of people's creative juices flowing -
I looked up this example of using a OrderDict to easily provide section/data in a uiTableView. The version that @ccc does turns out to be forward thinking. This version does not work in py3.5, but because of the section_key method, only one change is required to get it to work in py3.5
Maybe there is a more efficient or effective way to do it. But one change will get it to work in 3.5.def section_key(self, section): #return self.data.keys()[section] --> works in 2.7, not 3.5 return list(self.data.keys())[section]
Thought it was worth posting.
-