Python Forum
tkinter - update/refresh treeview
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
tkinter - update/refresh treeview
#1
I've got a treeview widget that is supplied data from an sql database.

I've been trying all day to make it so when I add a row to the database that the treeview instantly updates. I can't even begin to explain what I've tried so far but it's mostly based around trying to re-run def populate_tab_tree from the end of def on_save_button. I've also tried pasting the code into the end of my on_save_button method.

Needless to say, it's failed every time.

Can anyone point me in the right direction please.

Thank you

###### TO DO #######
"""
Simpligy the way buttons are added. 
Scrollbar not working
update treeview when new contact added to database
id row (use rowid? treeview messed up)
edit contact in database (select record, insert into entry box)
delete contact in databse
"""
#####################


from tkinter import *
from tkinter.ttk import *
import sqlite3

### Create tkinter window ##
root = Tk()
root.title("Bookkeeping")
root.geometry("1024x768") 
#root.attributes("-fullscreen",1)

### Add a Notebook to window ###
notebook = Notebook(root)
notebook.pack(fill="both", expand=1, pady=15)

### Class to add tabs to the notebook. Methods allow to add a Treeview, populate treeview ###
class Tab:
    def __init__(self, tab):
        self.tab = tab

        self.tab = Frame(notebook)
        self.tab.pack(fill="both", expand=1)
        notebook.add(self.tab, text=str(tab)) 

    def tab_tree(self, column_names):
        self.column_names = column_names    
        
        self.treeview_frame = Frame(self.tab)
        self.treeview_frame.pack(fill="both", expand=1)
        
        self.tree_scroll = Scrollbar(self.treeview_frame)
        self.tree_scroll.pack(side=RIGHT, fill=Y) 
        self.tab_tree = Treeview(self.treeview_frame, yscrollcommand=self.tree_scroll.set, selectmode="extended") 
        self.tab_tree.pack(fill="both", expand=YES)        
        
        self.tab_tree['columns'] = column_names
        self.tab_tree.column("#0", width=0, stretch=NO)
        self.tab_tree.heading("#0", text="")
        for name in column_names:
            self.tab_tree.column(name, minwidth=25, width=50) 
            self.tab_tree.heading(name, text=name)                  
    
    def populate_tab_tree(self, table, columns):
        self.table = table
        self.columns = columns

        conn = sqlite3.connect('Bookkeeping_Database.sqlite3')
        cur = conn.cursor()
        cur.execute("CREATE TABLE IF NOT EXISTS " + self.table + " (" + " TEXT, ".join(self.columns) +" TEXT)")
        cur.execute("SELECT * FROM " + self.table)
        records = cur.fetchall()     
        conn.commit()
        conn.close()          

        count=0
        for row in records:
            self.tab_tree.insert(parent='', index='end', iid=count, text='', values=row)
            count+=1            
               
    
### Class to create contact tab ###
class Create_contact_tab:
    def __init__ (self, tab_name, new_contact_button_name, column_names):
        self.tab_name = tab_name
        self.new_contact_button_name = new_contact_button_name
        self.tab_name = tab_name 
        self.column_names = column_names

        self.contact_tab = Tab(self.tab_name)
        self.contact_tab.tab_tree(column_names)
        self.contact_tab.populate_tab_tree(tab_name, column_names)   
        #self.select_record()     

        self.new_contact_button = Button(self.contact_tab.tab, text=(self.new_contact_button_name), command=self.new_contact_window)
        self.new_contact_button.pack(side=LEFT, padx=10, pady=10) 

        self.edit_contact_button = Button(self.contact_tab.tab, text="Edit", command=self.edit_contact_window)
        self.edit_contact_button.pack(side=LEFT, padx=10, pady=10) 

        self.delete_contact_button = Button(self.contact_tab.tab, text="Delete")
        self.delete_contact_button.pack(side=LEFT, padx=10, pady=10)
    
    def new_contact_window(self):
        self.new_contact_window = New_contact_window(self.tab_name) 
        self.new_contact_window.create_entry_boxes(self.column_names)     
        self.new_contact_window.save_button()
        self.new_contact_window.close_button()

    def edit_contact_window(self):
        self.edit_contact_window = Edit_contact_window(self.tab_name)
        self.edit_contact_window.create_entry_boxes(self.column_names)  
        self.edit_contact_window.save_button()
        self.edit_contact_window.close_button()
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""        
    def select_record(self):
        selected = self.contact_tab.tab_tree.focus()
        values = self.contact_tab.tab_tree(selected, 'values')
        print(values)
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

### Class to create new contact window ###
class New_contact_window:
    def __init__(self, tab_name):
        self.window = tab_name
        self.table_name = tab_name

        self.window = Toplevel()
        self.window.title("Add New " + self.table_name)
        
        self.frame = Frame(self.window)
        self.frame.pack(fill="both", expand=1, pady=10)
        
        self.detail_name_dictionary = {}
        self.detail_name_list_keys = []
    
    def create_entry_boxes(self, column_names):      
        self.column_names = column_names

        row=1
        column=1
        for detail_name in self.column_names:
            self.label = Label(self.frame, text=detail_name) 
            self.label.grid(row=row, column=column, padx=10) 
            column +=1
            self.entry_box = Entry(self.frame) 
            self.entry_box.grid(row=row, column=column, padx=10)
            row +=1
            column -=1

            self.detail_name_list_keys.append(detail_name) 
            self.detail_name_dictionary[detail_name] = self.entry_box                

    def save_button(self):
        self.save_button = Button(self.frame, text="Save", command=self.on_save_button)
        self.save_button.grid(row=11, column=2, padx=10, pady=10) 
    
    def on_save_button(self):
        inputted_data=[]
        values = []
        if len(self.entry_box.get()) == 0:
            pass
        else:
            for detail_name in self.detail_name_list_keys:
                entry_value = self.detail_name_dictionary[detail_name].get() 
                inputted_data.append(entry_value)
                values.append("?")
            inputted_data=tuple(inputted_data)
            values = ('(' + str(', '.join([str(i[0]) for i in values])) + ')')

            conn = sqlite3.connect('Bookkeeping_Database.sqlite3')
            cur = conn.cursor()
            cur.execute("CREATE TABLE IF NOT EXISTS " + self.table_name + " (" + " TEXT, ".join(self.detail_name_list_keys) +" TEXT)")
            cur.execute("INSERT INTO "+ self.table_name +"(" + ", ".join(self.detail_name_list_keys) + ") VALUES" + values + "", inputted_data,)
            conn.commit()
            conn.close()       

            saved_label = Label (self.frame, text="Saved") 
            saved_label.grid(row=12, column=2)

            self.create_entry_boxes(column_names)

    def close_button(self):
        self.close_button = Button(self.frame, text="Close", command=self.window.destroy)
        self.close_button.grid(row=11, column=1, padx=10, pady=10)    

### Class to create contact edit window ###
class Edit_contact_window(New_contact_window):
    def __init__ (self, tab_name):
        self.window = tab_name
        self.table_name = tab_name

        self.window = Toplevel()
        self.window.title("Edit " + self.table_name)
        
        self.frame = Frame(self.window)
        self.frame.pack(fill="both", expand=1)
        
        self.detail_name_dictionary = {}
        self.detail_name_list_keys = []    

### Add contact tabs ###
column_names = [    "ID",
                    "Company",
                    "Name",
                    "Street",
                    "Town",
                    "City",
                    "County",
                    "Postcode", 
                    "Email", 
                    "Phone", 
                    ]

customer_tab = Create_contact_tab("Customers", "Add New Customer", column_names)


vendor_tab = Create_contact_tab("Vendors", "Add New Vendor", column_names)

root.mainloop()
Reply


Messages In This Thread
tkinter - update/refresh treeview - by snakes - May-11-2021, 10:33 PM
RE: tkinter - update/refresh treeview - by MrTim - May-12-2021, 12:35 PM
RE: tkinter - update/refresh treeview - by MrTim - May-12-2021, 12:43 PM
RE: tkinter - update/refresh treeview - by snakes - May-13-2021, 07:10 AM
RE: tkinter - update/refresh treeview - by aynous19 - Dec-02-2023, 07:05 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Doubt approach update 2 Treeview at the same time TomasSanchexx 7 2,046 Sep-19-2023, 01:19 AM
Last Post: SaintOtis12
  [Tkinter] Update label if there are no records in treeview TomasSanchexx 1 977 Aug-20-2023, 04:45 PM
Last Post: menator01
  [Tkinter] How to insert data json to treeview tkinter? Shakanrose 8 4,578 Jan-19-2023, 03:58 PM
Last Post: Shakanrose
  [Tkinter] Different rows colours in treeview tkinter Krissstian 1 1,317 Nov-20-2022, 09:59 PM
Last Post: woooee
  [Tkinter] About Tkinter Treeview.selection_get() usage. water 3 8,447 Feb-12-2022, 02:19 PM
Last Post: water
  Can't get tkinter database aware cascading comboboxes to update properly dford 6 3,700 Jan-11-2022, 08:37 PM
Last Post: deanhystad
  [Tkinter] [split] Is there a way to embed a treeview as a row inside another treeview? CyKlop 5 3,434 Oct-20-2021, 12:14 AM
Last Post: CyKlop
  [Tkinter] Update variable using tkinter entry methon drSlump 6 5,280 Oct-15-2021, 08:01 AM
Last Post: drSlump
  [PyQt] Refresh x-labels in matplotlib animation widget JohnT 5 3,825 Apr-23-2021, 07:40 PM
Last Post: JohnT
  [Tkinter] acceleration of data output in treeview tkinter Vladimir1984 4 4,257 Nov-21-2020, 03:43 PM
Last Post: Vladimir1984

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020