How can I insert records into the frame under the headers using tkinter?

122 views Asked by At
import tkinter as tk
from tkinter import ttk
import customtkinter as ctk

class FieldsFrame(ctk.CTkFrame):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)

        # Grid Configuration
        self.rowconfigure(0, weight = 1)
        self.columnconfigure(0, weight = 1)
        self.columnconfigure(1, weight = 1)
        self.columnconfigure(2, weight = 1)
        self.columnconfigure(3, weight = 1)
        self.columnconfigure(4, weight = 1)
        self.columnconfigure(5, weight = 1)
        self.columnconfigure(6, weight = 1)

        self.grid(row = 0, column = 0, columnspan = 3, sticky = "WES", padx = 10, pady = 0)
        
        # Create Widgets
        self._create_widgets()

        
    def _create_widgets(self):
        options = {'padx': 5, 'pady': 5, 'font': ("Century Gothic", 20)}
        self.LRowid = ctk.CTkLabel(
            self,
            text = 'rowid',
            **options
        )
        self.LRowid.grid(row = 0, column = 0, sticky = "N")

        self.LSubject = ctk.CTkLabel(
            self,
            text = 'Subject',
            **options
        )
        self.LSubject.grid(row = 0, column = 1, sticky = "N")
        
        self.LScore = ctk.CTkLabel(
            self,
            text = 'Score',
            **options
        )
        self.LScore.grid(row = 0, column = 2, sticky = "N")
        
        self.LTotal = ctk.CTkLabel(
            self,
            text = 'Total',
            **options
        )
        self.LTotal.grid(row = 0, column = 3, sticky = "N")
        
        self.LWorktype = ctk.CTkLabel(
            self,
            text = 'Worktype',
            **options
        )
        self.LWorktype.grid(row = 0, column = 4, sticky = "N")
        
        self.LDate = ctk.CTkLabel(
            self,
            text = 'Date',
            **options
        )
        self.LDate.grid(row = 0, column = 5, sticky = "N")
        
        self.LEval = ctk.CTkLabel(
            self,
            text = 'Evaluation',
            **options
        )
        self.LEval.grid(row = 0, column = 6, sticky = "N")

class DatabaseFrame(ctk.CTkScrollableFrame):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)
        
        # Grid Config
        self.rowconfigure(0, weight = 1)
        self.columnconfigure(0, weight = 1)
        self.columnconfigure(1, weight = 1)
        self.columnconfigure(2, weight = 1)
        self.columnconfigure(3, weight = 1)
        self.columnconfigure(4, weight = 1)
        self.columnconfigure(5, weight = 1)
        self.columnconfigure(6, weight = 1)

        self.grid(row = 1, column = 0, columnspan = 3, sticky = "NWES", padx = 10, pady = 10)

        # Create Widgets from data
          
class InputFrame(ctk.CTkFrame):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)

        # Grid Layout Configuration
        self.rowconfigure(0, weight = 1)
        self.rowconfigure(1, weight = 1)
        self.rowconfigure(2, weight = 1)
        self.columnconfigure(0, weight = 1)
        self.columnconfigure(1, weight = 2)
        self.columnconfigure(2, weight = 1)
        self.columnconfigure(3, weight = 2)


        self.configure(
            # Insert color here
        )
        self._create_widgets()
        self.grid(row = 2, column = 1, columnspan = 1, sticky = "nsew", ipadx = 20, ipady = 20, padx = 30, pady = 10)
        
    def _create_widgets(self):
        _label_options = {'padx': 10, 'pady': 5, 'font': ("Century Gothic", 20)}
        _entry_options = {'fg_color': "white", 'corner_radius': 10}

        # Create subject label and entries
        self.LSubject = ctk.CTkLabel(
            self,
            text = "Enter subject:",
            **_label_options
        ).grid(row = 0, column = 0, sticky = "w")
        
        self.LSubject = ctk.CTkEntry(
            self,
            placeholder_text = "Enter subject:",
            **_entry_options
        ).grid(row = 0, column = 1, sticky = "ew")

        # Create score label and entries
        self.LScore = ctk.CTkLabel(
            self,
            text = "Enter score:",
            **_label_options
        ).grid(row = 0, column = 2, sticky = "w")

        self.LScore = ctk.CTkEntry(
            self,
            placeholder_text = "Enter score:",
            **_entry_options
        ).grid(row = 0, column = 3, sticky = "ew")

        # Create total label and entries
        self.LTotal = ctk.CTkLabel(
            self,
            text = "Score over total:",
            **_label_options
        ).grid(row = 1, column = 2, sticky = "w")

        self.LTotal = ctk.CTkEntry(
            self,
            placeholder_text = "Score over total:",
            **_entry_options
        ).grid(row = 1, column = 3, sticky = "ew")

        # Create Worktype label and entries
        self.LWorktype= ctk.CTkLabel(
            self,
            text = "Enter worktype:",
            **_label_options
        ).grid(row = 1, column = 0, sticky = "w")

        self.LWorktype = ctk.CTkEntry(
            self,
            placeholder_text = "Enter worktype:",
            **_entry_options
        ).grid(row = 1, column = 1, sticky = "ew")

        # Create Date label and entries
        self.LDate = ctk.CTkLabel(
            self,
            text = "Enter date:",
            **_label_options
        ).grid(row = 2, column = 0, sticky = "w")
        
        self.LDate = ctk.CTkEntry(
            self,
            placeholder_text = "Enter date:",
            **_entry_options
        ).grid(row = 2, column = 1, sticky = "ew")

    


class MainApp(ctk.CTk):
    def __init__(self):
        super().__init__()
        self.width = self.winfo_screenwidth()
        self.height = self.winfo_screenheight()
        self.title("Test Window")
        self.geometry(f"{self.width}x{self.height}")
        self.state("zoomed")
        # self.resizable(0, 0)
        
        self.rowconfigure(0, weight = 1)
        self.rowconfigure(1, weight = 4)
        self.rowconfigure(2, weight = 1)
        self.columnconfigure(0, weight = 1)
        self.columnconfigure(1, weight = 2)
        self.columnconfigure(2, weight = 1)

        self.db_frame = DatabaseFrame(self)
        self.input_frame = InputFrame(self)
        self.fields_frame = FieldsFrame(self)

Main_app = MainApp()
Main_app.mainloop()

I want to insert records into columns from a database. I'm fairly new to GUI so I'm not quite sure how to even start doing it.

I tried looping through the list and only accessing the second index of an SQLite record list. but I also thought about how to go about sorting the records by subject or date.

1

There are 1 answers

0
Alexander On BEST ANSWER

There are literally countless ways you could go about doing this. One example would be to use entry widgets for each of the columns in the table and line them up like rows beneath each of the header labels. Then when you go to add the data it will be editable.

Here is an example where I added a button to your input interface and when clicked the MainApp extracts all the information from the input_frame, and then inserts that information into a row of Entry widgets inside of the db_frame. I had to make a couple of changes to your code, but I think it's enough to get you started.

import tkinter as tk
from tkinter import ttk
import customtkinter as ctk

class FieldsFrame(ctk.CTkFrame):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)

        # Grid Configuration
        self.rowconfigure(0, weight = 1)
        self.columnconfigure(0, weight = 1)
        self.columnconfigure(1, weight = 1)
        self.columnconfigure(2, weight = 1)
        self.columnconfigure(3, weight = 1)
        self.columnconfigure(4, weight = 1)
        self.columnconfigure(5, weight = 1)
        self.columnconfigure(6, weight = 1)

        self.grid(row = 0, column = 0, columnspan = 3, sticky = "WES", padx = 10, pady = 0)

        # Create Widgets
        self._create_widgets()


    def _create_widgets(self):
        options = {'padx': 5, 'pady': 5, 'font': ("Century Gothic", 20)}
        self.LRowid = ctk.CTkLabel(
            self,
            text = 'rowid',
            **options
        )
        self.LRowid.grid(row = 0, column = 0, sticky = "N")

        self.LSubject = ctk.CTkLabel(
            self,
            text = 'Subject',
            **options
        )
        self.LSubject.grid(row = 0, column = 1, sticky = "N")

        self.LScore = ctk.CTkLabel(
            self,
            text = 'Score',
            **options
        )
        self.LScore.grid(row = 0, column = 2, sticky = "N")

        self.LTotal = ctk.CTkLabel(
            self,
            text = 'Total',
            **options
        )
        self.LTotal.grid(row = 0, column = 3, sticky = "N")

        self.LWorktype = ctk.CTkLabel(
            self,
            text = 'Worktype',
            **options
        )
        self.LWorktype.grid(row = 0, column = 4, sticky = "N")

        self.LDate = ctk.CTkLabel(
            self,
            text = 'Date',
            **options
        )
        self.LDate.grid(row = 0, column = 5, sticky = "N")

        self.LEval = ctk.CTkLabel(
            self,
            text = 'Evaluation',
            **options
        )
        self.LEval.grid(row = 0, column = 6, sticky = "N")

class DatabaseFrame(ctk.CTkScrollableFrame):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)

        # Grid Config
        self.rowconfigure(0, weight = 1)
        self.columnconfigure(0, weight = 1)
        self.columnconfigure(1, weight = 1)
        self.columnconfigure(2, weight = 1)
        self.columnconfigure(3, weight = 1)
        self.columnconfigure(4, weight = 1)
        self.columnconfigure(5, weight = 1)
        self.columnconfigure(6, weight = 1)

        self.grid(row = 1, column = 0, columnspan = 3, sticky = "NWES", padx = 10, pady = 10)
        self.cells = []
        for i in range(6):
            row = []
            for j in range(7):
                cell = ctk.CTkEntry(self, width=250)
                cell.grid(row=i, column=j)
                if j == 0:
                    cell.insert(tk.END, str(i))
                row.append(cell)
            self.cells.append(row)



class InputFrame(ctk.CTkFrame):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)

        # Grid Layout Configuration
        self.rowconfigure(0, weight = 1)
        self.rowconfigure(1, weight = 1)
        self.rowconfigure(2, weight = 1)
        self.columnconfigure(0, weight = 1)
        self.columnconfigure(1, weight = 2)
        self.columnconfigure(2, weight = 1)
        self.columnconfigure(3, weight = 2)
        self._parent = parent


        self.configure(
            # Insert color here
        )
        self._create_widgets()
        self.grid(row = 2, column = 1, columnspan = 1, sticky = "nsew", ipadx = 20, ipady = 20, padx = 30, pady = 10)

    def _create_widgets(self):
        _label_options = {'padx': 10, 'pady': 5, 'font': ("Century Gothic", 20)}
        _entry_options = {'fg_color': "white", 'corner_radius': 10}

        # Create subject label and entries
        self.LSubject1 = ctk.CTkLabel(
            self,
            text = "Enter subject:",
            **_label_options
        )
        self.LSubject1.grid(row = 0, column = 0, sticky = "w")

        self.LSubject2 = ctk.CTkEntry(
            self,
            placeholder_text = "Enter subject:",
            **_entry_options
        )
        self.LSubject2.grid(row = 0, column = 1, sticky = "ew")

        # Create score label and entries
        self.LScore1 = ctk.CTkLabel(
            self,
            text = "Enter score:",
            **_label_options
        )
        self.LScore1.grid(row = 0, column = 2, sticky = "w")

        self.LScore2 = ctk.CTkEntry(
            self,
            placeholder_text = "Enter score:",
            **_entry_options
        )
        self.LScore2.grid(row = 0, column = 3, sticky = "ew")

        # Create total label and entries
        self.LTotal1 = ctk.CTkLabel(
            self,
            text = "Score over total:",
            **_label_options
        )
        self.LTotal1.grid(row = 1, column = 2, sticky = "w")

        self.LTotal2 = ctk.CTkEntry(
            self,
            placeholder_text = "Score over total:",
            **_entry_options
        )
        self.LTotal2.grid(row = 1, column = 3, sticky = "ew")

        # Create Worktype label and entries
        self.LWorktype1= ctk.CTkLabel(
            self,
            text = "Enter worktype:",
            **_label_options
        )
        self.LWorktype1.grid(row = 1, column = 0, sticky = "w")

        self.LWorktype2 = ctk.CTkEntry(
            self,
            placeholder_text = "Enter worktype:",
            **_entry_options
        )
        self.LWorktype2.grid(row = 1, column = 1, sticky = "ew")

        # Create Date label and entries
        self.LDate1 = ctk.CTkLabel(
            self,
            text = "Enter date:",
            **_label_options
        )
        self.LDate1.grid(row = 2, column = 0, sticky = "w")

        self.LDate2 = ctk.CTkEntry(
            self,
            placeholder_text = "Enter date:",
            **_entry_options
        )
        self.LDate2.grid(row = 2, column = 1, sticky = "ew")

        self.button = ctk.CTkButton(self, text="submit", command=self._parent.onPress).grid(row=2, column=3)




class MainApp(ctk.CTk):
    def __init__(self):
        super().__init__()
        self.width = self.winfo_screenwidth()
        self.height = self.winfo_screenheight()
        self.title("Test Window")
        self.geometry(f"{self.width}x{self.height}")
        self.state("zoomed")
        # self.resizable(0, 0)

        self.rowconfigure(0, weight = 1)
        self.rowconfigure(1, weight = 4)
        self.rowconfigure(2, weight = 1)
        self.columnconfigure(0, weight = 1)
        self.columnconfigure(1, weight = 2)
        self.columnconfigure(2, weight = 1)

        self.db_frame = DatabaseFrame(self)
        self.input_frame = InputFrame(self)
        self.fields_frame = FieldsFrame(self)
        self.row_num = 0

    def onPress(self):
        for i, entry in enumerate(
            [self.input_frame.LSubject2, self.input_frame.LScore2,
             self.input_frame.LTotal2, self.input_frame.LWorktype2,
             self.input_frame.LDate2]
        ):
            text = entry.get()
            self.db_frame.cells[self.row_num][i+1].insert("0", str(text))



Main_app = MainApp()
Main_app.mainloop()