omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    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.


    Tableview reload

    Pythonista
    4
    19
    5815
    Loading More Posts
    • 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.
    • Rufat
      Rufat last edited by ccc

      Hi, was wondering how can I reload tableview in my form, it does not give me any mistake, data inserts in database and I can see it after reloading the form. But can I reload tableview without reloading from? Thanks.

      data = MyTableViewDataSource()
      v = ui.TableView()
      
      def button_tapped(sender):
      	sqliteConnection = db.connect('pythonsqlite.db')
      	cursor = sqliteConnection.cursor()
      	print("Connected to SQLite")
      		
              # adding single record now
      	sql_add_data = "INSERT INTO Names (Name, Surname) VALUES ('?','?')"
      	print(sql_add_data)
      	cursor.execute(sql_add_data)
      	sqliteConnection.commit()
      	print("Record successfully Added ")
      	print('button tapped')
      	v['tableview1'].reload()
      	
      v['tableview1'].data_source=data
      
      v = ui.load_view('MyForm')
      v['tableview1'].data_source=MyTableViewDataSource()
      v.present('sheet')
      
      1 Reply Last reply Reply Quote 0
      • JonB
        JonB last edited by

        if i undertstand your question -- you want to insert a row, but not reload the whole table, since reload loses your place?

        That is what insert_rows does -- you pass in a list of rows, or a list of (section,row)'s, and that lets the tableview know which cells have been inserted -- it will then query thr data source for those new rows, and will animate the insertion. you need to make sure your data source knows about the new rows first, and you need to know which rows got inserted.

        1 Reply Last reply Reply Quote 0
        • JonB
          JonB last edited by

          also, i will point out that you seem to be creating two different data sources -- one unnamed one initially, then you use data in the button callback. Probably not what you intended.

          1 Reply Last reply Reply Quote 0
          • Rufat
            Rufat last edited by

            Thank you, that is the problem I can’t let the tableview to know that it is a new rows available.

                        view = ui.load_view('MyForm')
            	view['tableview1'].reload_data()
            	view['tableview1'].data_source = MyTableViewDataSource()
            
            1 Reply Last reply Reply Quote 0
            • JonB
              JonB last edited by

              Can you edit your post so the whitespace is correct? Make sure the back ticks are on their own line.

              Use insert_rows instead of reload.
              Don't use datasource=MyTableViewDataSource() in your button action. Your datasource should already be instantiated.

              Also it would help if you post your datasource code -- is your datasource reading from the database each time it is called?

              1 Reply Last reply Reply Quote 0
              • Rufat
                Rufat last edited by

                This is the full code

                import ui
                import sqlite3 as db
                
                conn = db.connect('pythonsqlite.db')
                conn.row_factory = lambda cursor, row: row[0]
                c = conn.cursor()
                ids = c.execute('SELECT name FROM Names').fetchall()
                ids1 = c.execute('SELECT surname FROM Names').fetchall()
                
                class MyTableViewDataSource (object):			
                		
                def tableview_number_of_sections(self, tableview):
                	# Return the number of sections (defaults to 1)
                  return 1
                
                def tableview_number_of_rows(self, tableview, section):
                	# Return the number of rows in the section
                  return len(ids)
                
                def tableview_cell_for_row(self, tableview, section, row):
                	# Create and return a cell for the given section/row
                	
                	self.data = ids
                	self.data1 = ids1
                	self.cells = [ui.TableViewCell('value1') #'subtitle'
                                  for _ in range(len(self.data))]
                	cell = self.cells[row]
                	cell.text_label.text = self.data[row]
                	cell.detail_text_label.text = self.data1[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.
                	return ('Name')
                	
                def tableview_can_delete(self, tableview, section, row):
                	# Return True if the user should be able to delete the given row.
                	return True
                
                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 True
                
                def tableview_delete(self, tableview, section, row):
                	# Called when the user confirms deletion of the given row.
                	print ('Delete row ' + tableview.data_source.data[row])
                	sqliteConnection = db.connect('pythonsqlite.db')
                	cursor = sqliteConnection.cursor()
                	print("Connected to SQLite")
                	
                	# Deleting single record now
                	sql_delete_query = "DELETE from Names where Name=""'"+tableview.data_source.data[row]+"'"
                	print(sql_delete_query)
                	cursor.execute(sql_delete_query)
                	sqliteConnection.commit()
                	print("Record deleted successfully ")
                	
                	del tableview.data_source.data[row]
                	del tableview.data_source.data1[row]
                	cursor.close()
                	tableview.reload()
                	pass
                
                def tableview_move_row(self, tableview, from_section, from_row, to_section, to_row):
                	# Called when the user moves a row with the reordering control (in editing mode).
                	pass
                	
                def addBtn(sender):
                	sqliteConnection = db.connect('pythonsqlite.db')
                	cursor = sqliteConnection.cursor()
                	print("Connected to SQLite")
                	# adding single record now
                	sql_add_data = "INSERT INTO Names (Name, Surname) VALUES ('?','?')"
                	print(sql_add_data)
                	cursor.execute(sql_add_data)
                	sqliteConnection.commit()
                	print("Record successfully Added ")
                
                v = ui.load_view('MyForm')
                v['tableview1'].data_source = MyTableViewDataSource()
                v.present('sheet')
                
                1 Reply Last reply Reply Quote 0
                • JonB
                  JonB last edited by

                  Ok, where to begin?

                  Your data source is providing cells based on ids , which you never update. So, of course your data source will never know about the update. When you add the rows, you should also update ids and ids1 . Even better than using a global variable, you should create an instance of your data source, and then add ids as an attribute to your instance.

                  Other issues:

                   self.cells = [ui.TableViewCell('value1') #'subtitle'
                                    for _ in range(len(self.data))]
                  

                  This is not doing what you think... cell for row gets called EVERY time a cell comes into view. You are creating and throwing away a zillion TableViewCells. If you want to reuse cells, fine, but create them in __init__ . But then don’t forget to append to it in your button callback.

                  You should never call reload, until your data source is prepared to provide the new rows (or in case of delete, your data source must know the rows are deleted). If you keep your data up to date, then you never actually need to call reload, unless you have somehow changed your entire table.

                  Tableviews can be a bit tricky — the whole idea is that the table view and tableviewcells are not the data, they are just a lightweight view showing a window to the data. Don’t worry about trying to cache the table view cells — just create a new cell, fill in the info about the row, and return it. The OS magic then handles displaying the cell. The OS will query your data source before the first view to figure out how many cells there will be, and then figures out how many cells will fit on the screen, and only asks for that many cells. As you scroll, it is asking for cells. If you call add or delete, it will ask for data about the inserted cells.

                  1 Reply Last reply Reply Quote 0
                  • Rufat
                    Rufat last edited by

                    Thank you so much, I’l try to figure it out. Just can’t find any live example in the web. But how it works for deleting? And same thing (System) doesn’t work for adding the rows.

                    1 Reply Last reply Reply Quote 0
                    • Rufat
                      Rufat last edited by

                      I did it, thank you so much!

                      1 Reply Last reply Reply Quote 0
                      • JonB
                        JonB last edited by

                        You should post your solution (or a link to gist) back here to help others that might have similar issues.

                        1 Reply Last reply Reply Quote 0
                        • Rufat
                          Rufat last edited by Rufat

                          Here is how it works for me.

                               import ui
                               import sqlite3 as db
                               import dialogs
                          
                               conn = db.connect('pythonsqlite.db')
                               conn.row_factory = lambda cursor, row: row[0]
                               c = conn.cursor()
                              ids = c.execute('SELECT name FROM Names').fetchall()
                              ids1 = c.execute('SELECT surname FROM Names').fetchall()
                          
                          
                            class MyTableViewDataSource (object):
                             def __init__(self):
                          	self.items = ids		
                          	self.items1 = ids1
                          	
                          def tableview_number_of_sections(self, tableview):
                          	# Return the number of sections (defaults to 1)
                          	return 1
                          
                          def tableview_number_of_rows(self, tableview, section):
                          	# Return the number of rows in the section
                          	return len(self.items)
                          
                          def tableview_cell_for_row(self, tableview, section, row):
                          	# Create and return a cell for the given section/row
                          	cell = ui.TableViewCell('subtitle')
                          	cell.text_label.text = self.items[row]
                          	cell.detail_text_label.text = self.items1[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.
                          	return ('Name')
                          	
                          
                          def tableview_can_delete(self, tableview, section, row):
                          	# Return True if the user should be able to delete the given row.
                          	return True
                          
                          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 True
                          
                          def tableview_delete(self, tableview, section, row):
                          	# Called when the user confirms deletion of the given row.
                          	#my = ("Name=""'"+tableview.data_source.data[row]+"'")
                          	#print(my)
                          	print ('Delete row ' + tableview.data_source.items[row])
                          	sqliteConnection = db.connect('pythonsqlite.db')
                          	cursor = sqliteConnection.cursor()
                          	print("Connected to SQLite")
                          	
                          	# Deleting single record now
                          	sql_delete_query = "DELETE from Names where Name=""'"+tableview.data_source.items[row]+"'"
                          	print(sql_delete_query)
                          	cursor.execute(sql_delete_query)
                          	sqliteConnection.commit()
                          	print("Record deleted successfully ")
                          	
                          	del tableview.data_source.items[row]
                          	del tableview.data_source.items1[row]
                          	cursor.close()
                          	tableview.reload()
                          	pass
                          
                          def tableview_move_row(self, tableview, from_section, from_row, to_section, to_row):
                          	# Called when the user moves a row with the reordering control (in editing mode).
                          	pass
                          	
                          def add(self, sender):
                          	item = dialogs.input_alert('Add your name')
                          	item1 = dialogs.input_alert('Add your surname')
                          	if not item == None:
                          		self.items.append(item)
                          		self.items1.append(item1)
                          		view['tableview1'].reload()
                          	sqliteConnection = db.connect('pythonsqlite.db')
                          	cursor = sqliteConnection.cursor()
                          	print("Connected to SQLite")
                          	# adding single record now
                          	sql_add_data = "INSERT INTO Names (Name, Surname) VALUES "+"("+"'"+item+"'"+", "+"'"+item1+"'"+")"
                          	cursor.execute(sql_add_data)
                          	sqliteConnection.commit()
                          	cursor.close()
                          	
                          
                              view = ui.load_view('MyForm')
                              source = MyTableViewDataSource()
                              view.right_button_items = [ui.ButtonItem(title='add', action=source.add)]
                              view['tableview1'].data_source = source
                              view.present('sheet')
                          
                          1 Reply Last reply Reply Quote 0
                          • soydepr
                            soydepr last edited by

                            But. Can you bring a dB from another place and drop it in Pythonista and how u do it

                            cvp 1 Reply Last reply Reply Quote 0
                            • cvp
                              cvp @soydepr last edited by cvp

                              @soydepr you can import the db file into Pythonista but you could even open/access it without importing it, like explained here for a script.

                              Here under, how to import

                              1 Reply Last reply Reply Quote 0
                              • soydepr
                                soydepr last edited by soydepr

                                @cvp said:

                                import

                                For me the file is not accessible greyes out
                                https://imgur.com/KTy2w8o all my dB files are not selectables

                                cvp 2 Replies Last reply Reply Quote 0
                                • cvp
                                  cvp @soydepr last edited by cvp

                                  @soydepr said:

                                  greyes out

                                  You're right, sorry

                                  If you use "external files", it will work

                                  1 Reply Last reply Reply Quote 1
                                  • cvp
                                    cvp @soydepr last edited by cvp

                                    @soydepr other solution: you can share a .db file from the Files app to Pythonista and run the standard "import file" script

                                    soydepr 1 Reply Last reply Reply Quote 0
                                    • soydepr
                                      soydepr @cvp last edited by

                                      @cvp is original solution a bug ,

                                      Thanks I confirm your other solution does work

                                      cvp 1 Reply Last reply Reply Quote 0
                                      • cvp
                                        cvp @soydepr last edited by cvp

                                        @soydepr you can also try

                                        	f = dialogs.pick_document() 
                                        

                                        .db files are not grayed

                                        1 Reply Last reply Reply Quote 1
                                        • soydepr
                                          soydepr last edited by

                                          This post is deleted!
                                          1 Reply Last reply Reply Quote 0
                                          • First post
                                            Last post
                                          Powered by NodeBB Forums | Contributors