[Python] Moving a function from a frame class to a commands class in tkinter

Discussão em 'Python' iniciado por Stack, Abril 10, 2025.

  1. Stack

    Stack Membro Participativo

    I am learning OO programming by converting an existing app programmed in straight tkinter. I need to be able to access an entrybox in top_frame from a button in left_frame. I have managed to achieve this by passing an instance of top_frame to Left_frame and with the program as listed here it works. However I wanted to put all of the methods into a Commands class for clarity so that the frame classes set the UI and the Commands class does the work. In the code I can call methods in the commands class from left_frame and in simple terms they work. My problem is that I need to use the contents of top_frame.g_round in the list golfers method in the Commands class. The code as shown works if the command for my_list_btn is "self.list_golfers" (using the left_frame method) but if I try to use the Commands class version by calling "Commands.list_golfers" I get errors when trying to pass the required attributes. I have tried various answers but each give me errors. Could anyone help by showing me how to pass the necessary attributes to the method in the Commands class. I have gone through many videos/texts to try to work it out but clearly I have missed something. Thanks

    from tkinter import *
    import tkinter as tk
    from ttkbootstrap.constants import *
    import ttkbootstrap as tb
    from ttkbootstrap import Style
    from ttkbootstrap.scrolled import ScrolledText, ScrolledFrame
    #import sqlite3
    #from sqlite3 import Error
    from ttkbootstrap.dialogs import Messagebox


    class Commands(tb.Frame):
    def __init__(self,parent, left_frame_instance):
    super().__init__(parent)
    l_frame = left_frame_instance
    def list_golfers(self):
    x= self.l_frame.tframe1.g_round.get()
    print('list_golfers')
    print(x)

    def new_golfer():
    print('new_golfer')

    def report():
    print('report')

    def select():
    print('select')


    class Top_Frame(tb.Frame):

    def __init__(self, parent): # Create widgets
    super().__init__(parent,width=900, height=200, bootstyle ='light')

    self.pack(padx=10, pady=5, fill=BOTH)

    self.g_round = tb.Entry(self,width=3, font=("Courier",10))
    self.g_round.grid(row = 0, column=1,padx=10,pady=10)
    self.round_label = tb.Label(self, text = "You must enter the round number before proceeding --> ", font=('Courier', 10))
    self.round_label.grid(row=0,column=0,padx=10,pady=10)



    class Left_Frame(tb.Frame):
    def __init__(self,parent, top_frame_instance):
    super().__init__(parent,width=400, height=600, bootstyle ='light')
    self.tframe1 = top_frame_instance # Store reference to Frame1 instance


    self.pack(side='left',padx=10, pady=5, fill=BOTH, expand= True)

    self.create_Lwidgets()


    def list_golfers(self):
    x= self.tframe1.g_round.get()
    print('list_golfers')
    print(x)

    def create_Lwidgets(self):
    my_list_btn=tb.Button(self,text='list',bootstyle='success', command= self.list_golfers)
    my_list_btn.grid(row=0, column=0,padx=5,pady=5)

    list_frame = tb.Frame(self,width=200, height=800,bootstyle='primary')
    list_frame.grid(row=1, column=0,padx=5,pady=5, rowspan=18)

    my_listbox=Listbox(list_frame)
    my_listbox.pack(padx=0,pady=15, side = LEFT,fill='both')

    my_scrollbar = Scrollbar(list_frame)
    my_scrollbar.pack(side = RIGHT, fill = BOTH)

    my_listbox.config(yscrollcommand = my_scrollbar.set)
    my_scrollbar.config(command = my_listbox.yview)

    golfer_button= tb.Button(self, text='New Golfer',bootstyle ='success',command = Commands.new_golfer)
    golfer_button.grid(row=21, column=0,padx=10,pady=10)

    report_button= tb.Button(self, text='Generate Report',bootstyle ='success',command = Commands.report)
    report_button.grid(row=22, column=0,padx=10,pady=10)

    select_btn = tb.Button(self, text="Select", bootstyle = SUCCESS,command = Commands.select)
    select_btn.grid(row=4, column=1, pady=5, padx=5)

    id_label=tb.Label(self,text = 'id')
    id_label.grid(row=2,column=2,padx=10)

    g_id = tb.Entry(self,width=3, font=("Courier",10), state='disabled')
    g_id.grid(row = 2, column=3,padx=5,pady=5)





    class Right_Frame(tb.Frame):
    def __init__(self,parent):
    super().__init__(parent,width=400, height=600, bootstyle ='light')
    self.pack(side= 'right',padx=10, pady=5, fill=BOTH, expand=True)

    self.create_Rwidgets()
    #create widgets
    def create_Rwidgets(self):
    my_label = tb.Label(self, text = "Batch Scores", font=('Courier', 10))
    my_label.grid(row=0,column=0,padx=10,pady=10)

    Ts = Listbox(self, height = 30, width = 30)
    Ts.grid(row= 2, column= 0, sticky= N, columnspan = 5, padx= 10, pady= 15)

    class MyApp(tb.Window):
    def __init__(self):
    super().__init__(themename = 'terry')
    # self.root = root
    self.title("TTKBootstrap OOP Example")
    self.geometry("1000x1000")


    top_frame = Top_Frame(self)
    left_frame = Left_Frame(self,top_frame)
    right_frame = Right_Frame(self)
    commands = Commands(self, left_frame)

    if __name__ == "__main__":
    app = MyApp() # Create an instance of MyApp
    app.mainloop()

    Continue reading...

Compartilhe esta Página