Python Forum

Full Version: .get() from generated Entry widgets in tkinter
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I've been learning about classes and databases and thought I'd have a go at writing something that uses both features. Its a tkinter notebook that aims to collect details like name, address, email etc and save them to a sql database.

I've made a class that has (so far) three methods. __init__ creates the tab, request_details creates the entry boxes and save_button is hopefully going to .get() the inputted data and save it to the database.

I've got two problems I'd like to sort out. I can't work out how to use .get() to pull data from each entry box because each box is created using a for loop. I don't know if I need to aim to create a method in the class to use.get() or a function outside the class.

My other problem is related to the database and for a different forum. Ultimately, I want to create a table in my database using a list for column names instead of typing them in like I have done in my code. I think this problem is kinda related to how I'm hoping to add the data from the entry boxes.

I've tried sooo many things but all have failed so my code is back to where I started yesterday morning! I'm trying to keep it simple because even reading my own code can sometimes send me into a spin!

Thank you for any help.

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

### Create SQLite database and connect to it ###
conn = sqlite3.connect('Bookkeeping_Database.sqlite3')
cur = conn.cursor()

### Create tkinter window ###
root = Tk()
root.title("Bookkeeping")
root.geometry("800x600") 

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

### Class to add tabs to Notebook with a method to add entry boxes and a save button ###
class Create_tab:
    def __init__(self, tab):
        tab_name = str(tab)
        self.tab = tab
        self.tab = Frame(home_screen)
        self.tab.pack(fill="both", expand=1)
        home_screen.add(self.tab, text=tab_name)
        
    def request_details(self, detail_name):
        entry_box = Entry(self.tab)
        entry_box.grid(column=1)
        entry_box.insert(0, detail_name)
    
    def save_button(self):
        save_button = Button(self.tab, text="Save")
        save_button.grid(column=1)  
    
### Create Customers tab ###
def customer_tab():
    customer_tab = Create_tab("Customers")
    entry_boxes = ["Customer ID","Name","Address 1","Address 2","Address 3","Address 4", "Email Address", "Phone 1", "Phone 2"]
    cur.execute('CREATE TABLE IF NOT EXISTS Customers (customer_id TEXT, name TEXT, address_1 TEXT, address_2 TEXT, address_3 TEXT, address_4 TEXT, email Address TEXT, phone_1 TEXT, phone_2 TEXT)')   
    for detail in entry_boxes:
        customer_details = customer_tab.request_details(detail)  
    save_button = customer_tab.save_button()    

### Create Vendors tab ###
def vendor_tab():
    vendor_tab = Create_tab("Vendors")

    for detail in ["Name","Address 1","Address 2","Address 3","Address 4", "Email Address", "Phone 1", "Phone 2"]:
        vendor_details = vendor_tab.request_details(detail)

#Main
customer_tab()
vendor_tab()
root.mainloop()
You need to keep a reference to each Entry widget, you could store them in a dictionary for each tab with the keys as the detail_name's.
Thank you for replying.

It seems difficult for me! but would that mean in my request_details method I would also need to to start building a dictionary... the key being the detail_name that I send from the customer_tab function and the value being from a .get()?

Right now, I think I need to start again.

Is using a class the best way to go about this? So far, I don't quite see the point in using classes. It feels like it's a good way to build a tab but I'm struggling to do much with it once it's set out.

To make it easier for me to read I've removed the sql stuff.

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

### Create tkinter window ###
root = Tk()
root.title("Bookkeeping")
root.geometry("800x600") 

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

### Class to add tabs to Notebook with a method to add entry boxes and a save button ###
class Create_tab:
    def __init__(self, tab):
        tab_name = str(tab)
        self.tab = tab
        self.tab = Frame(home_screen)
        self.tab.pack(fill="both", expand=1)
        home_screen.add(self.tab, text=tab_name)
        
    def request_details(self, detail_name):
        entry_box = Entry(self.tab)
        entry_box.grid(column=1)
        entry_box.insert(0, detail_name)   

    def save_button(self):
        save_button = Button(self.tab, text="Save")
        save_button.grid(column=1)       

### Create Customers tab ###
def customer_tab():
    customer_tab = Create_tab("Customers")
    entry_boxes = ["Customer ID","Name","Address 1","Address 2","Address 3","Address 4", "Email Address", "Phone 1", "Phone 2"]
    for detail_name in entry_boxes:
        customer_details = customer_tab.request_details(detail_name)  
    save_button = customer_tab.save_button()     

### Create Vendors tab ###
def vendor_tab():
    vendor_tab = Create_tab("Vendors")

    for detail_name in ["Name","Address 1","Address 2","Address 3","Address 4", "Email Address", "Phone 1", "Phone 2"]:
        vendor_details = vendor_tab.request_details(detail_name)

#Main
customer_tab()
vendor_tab()
root.mainloop()
Yes using classes I find is the best way for working with GUI's
In the following modified version of your code, I have stored the entry's in dictionaries and shown access them in the save button event.
import tkinter as tk
from tkinter import ttk

### Create tkinter window ###


class App(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.title("Bookkeeping")
        self.geometry("800x600")

        ### Add a Notebook to window ###
        self.home_screen = ttk.Notebook(self)
        self.home_screen.pack(fill="both", expand=1, pady=15)
        self.create_customer_tab()
        self.create_vendor_tab()

    ### Create Customers tab ###
    def create_customer_tab(self):
        self.customer_tab = TabFrame(self.home_screen)
        entry_boxes = ["Customer ID", "Name", "Address 1", "Address 2",
                       "Address 3", "Address 4", "Email Address", "Phone 1",
                       "Phone 2"]
        for detail_name in entry_boxes:
            self.customer_tab.create_entrys(detail_name)

        self.customer_tab.create_save_button()
        self.customer_tab.save_button.bind('<Button-1>', self.on_save_button)

        self.home_screen.add(self.customer_tab, text="Customers")

    ### Create Vendors tab ###
    def create_vendor_tab(self):
        self.vendor_tab = TabFrame(self.home_screen)

        for detail_name in ["Name", "Address 1", "Address 2", "Address 3",
                            "Address 4", "Email Address", "Phone 1", "Phone 2"]:
            self.vendor_tab.create_entrys(detail_name)

        self.home_screen.add(self.vendor_tab, text="Vendors")

    def on_save_button(self, event):
        print('save clicked')
        entry_boxes = ["Customer ID", "Name", "Address 1", "Address 2",
                       "Address 3", "Address 4", "Email Address", "Phone 1",
                       "Phone 2"]
        for detail_name in entry_boxes:
            entry_value = self.customer_tab.entrys[detail_name].get()
            print(f'Entry {detail_name} = {entry_value}')


### Class to add tabs to Notebook with a method to add entry boxes and a save button ###
class TabFrame(tk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pack(fill="both", expand=1)
        self.entrys = {}

    def create_entrys(self, detail_name):
        entry_box = tk.Entry(self)
        entry_box.grid(column=1)
        entry_box.insert(0, detail_name)
        self.entrys[detail_name] = entry_box

    def create_save_button(self):
        self.save_button = tk.Button(self, text="Save")
        self.save_button.grid(column=1)


# Main
app = App()
app.mainloop()
Wow, a huge "thank you!"

I guess the order your code is written is far better than the way I wrote mine but I struggled to follow all of it. I did however manage to pull the parts I needed and add them to my code. It now all works the way I wanted. I've also managed to get it adapt depending on which Entry boxes you want in each tab.

I'm now just working out how to enter it to a sql database.

Thank you!

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

### Create SQLite database and connect to it ###
conn = sqlite3.connect('Bookkeeping_Database.sqlite3')
cur = conn.cursor()

### Create tkinter window ###
root = Tk()
root.title("Bookkeeping")
root.geometry("800x600") 

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

### Class to add tabs to Notebook with a method to add entry boxes and a save button ###
class Create_tab:
    def __init__(self, tab):
        self.tab_name = str(tab)
        self.tab = tab
        self.tab = Frame(home_screen)
        self.tab.pack(fill="both", expand=1)
        home_screen.add(self.tab, text=self.tab_name)
        self.detail_name_dictionary = {}
        self.detail_name_list_keys = []
        
    def create_entry_boxes(self, detail_name):
        self.detail_name = detail_name
        self.entry_box = Entry(self.tab)
        self.entry_box.grid(column=1)
        self.entry_box.insert(0, detail_name)   
        self.detail_name_dictionary[self.detail_name] = self.entry_box
        self.detail_name_list_keys.append(detail_name)      
        
    def save_button(self):
        self.save_button = Button(self.tab, text="Save")
        self.save_button.grid(column=1)    
    
    def on_save_button(self, event):
            for detail_name in self.detail_name_list_keys:
                entry_value = self.detail_name_dictionary[detail_name].get()
                print(f' {detail_name} = {entry_value}') 
        
            cur.execute("CREATE TABLE IF NOT EXISTS " + self.tab_name + " (" + " TEXT, ".join(self.detail_name_list_keys) +" TEXT)")
            cur.executemany("INSERT INTO "+ self.tab_name +"(" + ", ".join(self.detail_name_list_keys) + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", str(entry_value,))
            conn.commit()
            

### Create Customers tab ###
def create_customer_tab():
    customer_tab = Create_tab("Customers")

    entry_boxes = [ "Customer_ID",
                    "Company",
                    "Name",
                    "Address_1",
                    "Address_2",
                    "Address_3",
                    "Address_4", 
                    "Email", 
                    "Phone_1", 
                    "Phone_2",
                    ]
    for detail_name in entry_boxes:
        customer_tab.create_entry_boxes(detail_name)
        
    customer_tab.save_button()
    customer_tab.save_button.bind('<Button-1>', customer_tab.on_save_button)

#Main
create_customer_tab()

root.mainloop()
conn.close()