0

I am creating an app using Python Tkinter. For Which I need to have a scroll bar for canvas.

While Starting the app

I am trying to add new rows while the "Add New Row" button is pressed.

A new row is getting added up, but the scroll bar is not working.

After Adding Few Rows

Here Is My Code:

class AlterCreateTable:
def __init__(self) -> None:
    self.rows = {}
    self.row_num = -1
    pass

def initiate(self, database, uname=None, passw=None, sqlite=False):
    self.sqlite = sqlite
    self.uname = uname
    self.passw = passw
    self.database = database

    self.create_alter = tix.Tk()
    # self.create_alter.resizable(height=False, width=False)
    self.create_alter.title(f"Create Table")
    self.create_alter.geometry("570x400")

    main_frame = Frame(self.create_alter)
    main_frame.pack(expand=1, fill='both', anchor=CENTER)

    frame = Frame(main_frame)
    frame.place(relx=0.001, rely=0.01, relwidth=1)

    first_frame = Frame(frame)
    first_frame.pack(padx=10, fill=X)

    Label(first_frame, text='Create Table', font=10).grid(padx=10, row=0, columnspan=10)

    table_name_frame = Frame(first_frame)
    table_name_frame.grid(row=1, columnspan=10)
    Label(table_name_frame, text='Table Name :', font=10).grid(row=0, column=0, padx=20)

    self.table_name_entry = Entry(table_name_frame, font=10, width=15)
    self.table_name_entry.grid(row=0, column=1, padx=10, pady=10)

    Label(first_frame, text='Column Name', font=10).grid(row=2, column=0, padx=20, pady=5)
    Label(first_frame, text='Data Type', font=10).grid(row=2, column=1, padx=25, pady=5)
    pk = Label(first_frame, text='PK', font=10)
    pk.grid(row=2, column=2, padx=15, pady=5)
    uq = Label(first_frame, text='UQ', font=10)
    uq.grid(row=2, column=3, padx=15, pady=5)
    nn = Label(first_frame, text='NN', font=10)
    nn.grid(row=2, column=4, padx=15, pady=5)
    ai = Label(first_frame, text='AI', font=10)
    ai.grid(row=2, column=5, padx=15, pady=5)

    self.tip = tix.Balloon(self.create_alter)

    self.tip.bind_widget(pk, msg='Primary Key')
    self.tip.bind_widget(uq, msg='Unique Index')
    self.tip.bind_widget(nn, msg='Not Null')
    self.tip.bind_widget(ai, msg='Auto Increment')

    self.canvas =Canvas(frame, height=250, width=400, highlightbackground='black')
    self.canvas.pack(side=LEFT, fill=BOTH, expand=1, anchor=CENTER)

    scroll_bar = ttk.Scrollbar(frame, orient=VERTICAL, command=self.canvas.yview)
    scroll_bar.pack(side=RIGHT, fill=Y)

    def on_mouse_wheel(event):
        self.canvas.yview_scroll(-1 * (event.delta // 120), "units")

    self.canvas.bind("<Configure>", lambda e: self.canvas.configure(scrollregion=self.canvas.bbox('all')))

    self.canvas.bind_all("<MouseWheel>", on_mouse_wheel)

    self.canvas.configure(yscrollcommand=scroll_bar.set)

    self.second_frame = Frame(self.canvas)
    self.second_frame.place(relheight=1, relwidth=1, anchor=CENTER)
    
    self.canvas.create_window((0, 0), window=self.second_frame, anchor='nw')
    
    self.add_but = Button(main_frame, text='Add Next Row', font=10, command=self.add_row)
    self.add_but.place(relx=0.4, rely=0.9)

    self.create_rows()
    self.create_alter.mainloop()

def create_rows(self):
    
    types = ['INT', 'VARCHAR(30)', 'VARCHAR(50)', 'VARCHAR(100)', 'DATETIME', 'DECIMAL', 'FLOAT']
    cl_nm_1, dty_1, pk_1, uq_1, nn_1, ai_1 = Entry(self.second_frame, width=13, font=10), ttk.Combobox(self.second_frame, width=13, state='readonly', values=types), Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame)
    cl_nm_2, dty_2, pk_2, uq_2, nn_2, ai_2 = Entry(self.second_frame, width=13, font=10), ttk.Combobox(self.second_frame, width=13, state='readonly', values=types), Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame)
    cl_nm_3, dty_3, pk_3, uq_3, nn_3, ai_3 = Entry(self.second_frame, width=13, font=10), ttk.Combobox(self.second_frame, width=13, state='readonly', values=types), Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame)
    cl_nm_4, dty_4, pk_4, uq_4, nn_4, ai_4 = Entry(self.second_frame, width=13, font=10), ttk.Combobox(self.second_frame, width=13, state='readonly', values=types), Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame)
    cl_nm_5, dty_5, pk_5, uq_5, nn_5, ai_5 = Entry(self.second_frame, width=13, font=10), ttk.Combobox(self.second_frame, width=13, state='readonly', values=types), Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame)
    cl_nm_6, dty_6, pk_6, uq_6, nn_6, ai_6 = Entry(self.second_frame, width=13, font=10), ttk.Combobox(self.second_frame, width=13, state='readonly', values=types), Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame)
    cl_nm_7, dty_7, pk_7, uq_7, nn_7, ai_7 = Entry(self.second_frame, width=13, font=10), ttk.Combobox(self.second_frame, width=13, state='readonly', values=types), Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame)
    cl_nm_8, dty_8, pk_8, uq_8, nn_8, ai_8 = Entry(self.second_frame, width=13, font=10), ttk.Combobox(self.second_frame, width=13, state='readonly', values=types), Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame)
    cl_nm_9, dty_9, pk_9, uq_9, nn_9, ai_9 = Entry(self.second_frame, width=13, font=10), ttk.Combobox(self.second_frame, width=13, state='readonly', values=types), Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame)
    cl_nm_10, dty_10, pk_10, uq_10, nn_10, ai_10 = Entry(self.second_frame, width=13, font=10), ttk.Combobox(self.second_frame, width=13, state='readonly', values=types), Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame)
    cl_nm_11, dty_11, pk_11, uq_11, nn_11, ai_11 = Entry(self.second_frame, width=13, font=10), ttk.Combobox(self.second_frame, width=13, state='readonly', values=types), Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame)
    cl_nm_12, dty_12, pk_12, uq_12, nn_12, ai_12 = Entry(self.second_frame, width=13, font=10), ttk.Combobox(self.second_frame, width=13, state='readonly', values=types), Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame)
    cl_nm_13, dty_13, pk_13, uq_13, nn_13, ai_13 = Entry(self.second_frame, width=13, font=10), ttk.Combobox(self.second_frame, width=13, state='readonly', values=types), Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame)
    cl_nm_14, dty_14, pk_14, uq_14, nn_14, ai_14 = Entry(self.second_frame, width=13, font=10), ttk.Combobox(self.second_frame, width=13, state='readonly', values=types), Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame)
    cl_nm_15, dty_15, pk_15, uq_15, nn_15, ai_15 = Entry(self.second_frame, width=13, font=10), ttk.Combobox(self.second_frame, width=13, state='readonly', values=types), Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame),Checkbutton(self.second_frame)

    self.column_names = [cl_nm_1, cl_nm_2, cl_nm_3, cl_nm_4, cl_nm_5, cl_nm_6, cl_nm_7, cl_nm_8, cl_nm_9, cl_nm_10, cl_nm_11, cl_nm_12, cl_nm_13, cl_nm_14, cl_nm_15]
    self.datatypes = [dty_1, dty_2, dty_3, dty_4, dty_5, dty_6, dty_7, dty_8, dty_9, dty_10, dty_11, dty_12, dty_13, dty_14, dty_15]
    self.pks = [pk_1, pk_2, pk_3, pk_4, pk_5, pk_6, pk_7, pk_8, pk_9, pk_10, pk_11, pk_12, pk_13, pk_14, pk_15]
    self.uqs = [uq_1, uq_2, uq_3, uq_4, uq_5, uq_6, uq_7, uq_8, uq_9, uq_10, uq_11, uq_12, uq_13, uq_14, uq_15]
    self.nns = [nn_1, nn_2, nn_3, nn_4, nn_5, nn_6, nn_7, nn_8, nn_9, nn_10, nn_11, nn_12, nn_13, nn_14, nn_15]
    self.ais = [ai_1, ai_2, ai_3, ai_4, ai_5, ai_6, ai_7, ai_8, ai_9, ai_10, ai_11, ai_12, ai_13, ai_14, ai_15]
    
    self.minus_but = Button(self.second_frame, text='-', font=('bold', 15), command=self.minus_row)

    self.add_row()

#Add Row Funtion
def add_row(self):
    self.row_num += 1
    self.column_names[self.row_num].grid(row=self.row_num, column=0, pady=5, padx=20)
    self.datatypes[self.row_num].current(0)
    self.datatypes[self.row_num].grid(row=self.row_num, column=1, padx=12)
    self.pks[self.row_num].grid(row=self.row_num, column=2, padx=13)
    self.uqs[self.row_num].grid(row=self.row_num, column=3, padx=15)
    self.nns[self.row_num].grid(row=self.row_num, column=4, padx=15)
    self.ais[self.row_num].grid(row=self.row_num, column=5, padx=13)
    
    if self.row_num > 0:
        self.minus_but.grid(row=self.row_num, column=6)

    if self.row_num > 13:
        self.add_but.config(state='disabled')
    else:
        self.add_but.config(state='normal')

#Minus Row Function
def minus_row(self):
    self.column_names[self.row_num].grid_forget()
    self.datatypes[self.row_num].grid_forget()
    self.pks[self.row_num].grid_forget()
    self.uqs[self.row_num].grid_forget()
    self.nns[self.row_num].grid_forget()
    self.ais[self.row_num].grid_forget()
    self.row_num -= 1
    if self.row_num > 0:
        self.minus_but.grid(row=self.row_num, column=6)
    else:
        self.minus_but.grid_forget()


t = AlterCreateTable()
t.initiate('virtual_users', 'user name', 'password')

I even tried to add these two in the add_row() Function, But no use...

    self.create_alter.update_idletasks()
    self.create_alter.update()

Please Help Me!! Thanks In Advance..

Vishal N
  • 41
  • 3
  • I suggest that you use a class that inherits from frame to group all the checkbuttons and entries in one row – Matiiss Aug 14 '21 at 11:56
  • Change `self.canvas.bind("", ...)` to `self.second_frame.bind("", ...)`. Also you might want to try just using [this](https://stackoverflow.com/a/66215091/11106801) class that I created – TheLizzard Aug 14 '21 at 12:32
  • 1
    @TheLizzard Thanks for the help. That just working. And your frame is also great.. – Vishal N Aug 14 '21 at 16:26

0 Answers0