-3

So, I wanted to update the List of the first 9 lines from the file (Lista_Igraca.txt), that holds the Leaderboard, whenever I switch to the Leaderboard Frame. Because when I add any new information to the file by finishing the game and there is less than 10 inputs already loaded, the new inputs don't want to update. So I just tried calling the 2 functions LeaderboardPage.configure_leaderboard() and LeaderboardPage.leaderboard_creation() that should basically just take the first 9 items and put them on the Leaderboard Labels.
But when I do call them in the manner that is shown underneath in the MainMenu.button2_f() function I get this error message:
self.board1.config(text = Igraci_Printout[0])
AttributeError: type object 'LeaderboardPage' has no attribute 'board1'

I understand that this is an error telling me that I can not access the class attributes in this way... and is probably a fault of me not really entirely understanding everything there is to understand about classes just yet.

import tkinter as tk
import os

BIG_BUTTON_FONT = ('Lato',28)
BUTTON_FONT = ('Lato', 16)
TITLE_FONT = ('Copperplate Gothic Bold', 38)
BOARD_FONT = ('Arial', 15)

class MultiPage(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand = True)

        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}
        for F in (MainMenu, LeaderboardPage):
            frame = F(parent = container, controller = self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(MainMenu)
        
    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()


class MainMenu(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        self.button2 = tk.Button(self, text='Leaderboard', font = BIG_BUTTON_FONT, width=10, command = lambda: self.button2_f(controller))
        self.button2.pack(side='top', pady=0)

    def button2_f(self, controller):
        controller.show_frame(LeaderboardPage)
        LeaderboardPage.configure_leaderboard(LeaderboardPage, LeaderboardPage.leaderboard_creation(LeaderboardPage))


class LeaderboardPage(tk.Frame):

    if not os.path.isfile('Lista_Igraca.txt'):
        Lista_Igraca = open('Lista_Igraca.txt', 'x')
        Lista_Igraca.close()

    Lista_Igraca = open('Lista_Igraca.txt', 'r')
    br_stranice = 0
    marker = []
    igrac_class = 'place_hoder'
    num_igraca_class = -1

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        self.Lista_Igraca = open('Lista_Igraca.txt', 'r')
        num_igraca = sum(1 for line in self.Lista_Igraca)
        self.Lista_Igraca.close() 

        self.num_igraca_class = num_igraca

        Igraci_Printout = []
        Igraci_Printout = self.leaderboard_creation()

        self.board1 = tk.Label(self, text = Igraci_Printout[0], font = BOARD_FONT, bg = 'black', fg = 'white')
        self.board2 = tk.Label(self, text = Igraci_Printout[1], font = BOARD_FONT, bg = 'black', fg = 'white')
        self.board3 = tk.Label(self, text = Igraci_Printout[2], font = BOARD_FONT, bg = 'black', fg = 'white')
        self.board4 = tk.Label(self, text = Igraci_Printout[3], font = BOARD_FONT, bg = 'black', fg = 'white')
        self.board5 = tk.Label(self, text = Igraci_Printout[4], font = BOARD_FONT, bg = 'black', fg = 'white')
        self.board6 = tk.Label(self, text = Igraci_Printout[5], font = BOARD_FONT, bg = 'black', fg = 'white')
        self.board7 = tk.Label(self, text = Igraci_Printout[6], font = BOARD_FONT, bg = 'black', fg = 'white')
        self.board8 = tk.Label(self, text = Igraci_Printout[7], font = BOARD_FONT, bg = 'black', fg = 'white')
        self.board9 = tk.Label(self, text = Igraci_Printout[8], font = BOARD_FONT, bg = 'black', fg = 'white')

        self.frame1 = tk.Frame(self, bg = 'black', bd = 0)
        self.button1 = tk.Button(self.frame1, text = 'Next', font = BUTTON_FONT, command = lambda: self.next_page())
        self.button2 = tk.Button(self.frame1, text = 'Exit', font = BUTTON_FONT, command = lambda: self.exit_leaderboard(controller)) 
        self.button3 = tk.Button(self.frame1, text = 'Prev', font = BUTTON_FONT, command = lambda: self.previous_page())

        self.button1.pack(side = tk.RIGHT)
        self.button2.pack(side = tk.RIGHT, padx = 20)
        self.button3.pack(side = tk.RIGHT)

        self.board1.pack(side = tk.TOP, anchor = 'n')
        self.board2.pack(side = tk.TOP, anchor = 'n')
        self.board3.pack(side = tk.TOP, anchor = 'n')
        self.board4.pack(side = tk.TOP, anchor = 'n')
        self.board5.pack(side = tk.TOP, anchor = 'n')
        self.board6.pack(side = tk.TOP, anchor = 'n')
        self.board7.pack(side = tk.TOP, anchor = 'n')
        self.board8.pack(side = tk.TOP, anchor = 'n')
        self.board9.pack(side = tk.TOP, anchor = 'n')

        self.frame1.pack(side = tk.BOTTOM, pady = 30)

    def exit_leaderboard(self, controller):
        controller.show_frame(MainMenu)
        self.br_stranice = 1
        self.previous_page()

    def leaderboard_creation(self):
        if LeaderboardPage.Lista_Igraca.tell() not in self.marker:
            self.marker.append(LeaderboardPage.Lista_Igraca.tell())

        igrac = LeaderboardPage.Lista_Igraca.readline()
        counter1 = 0
        Igraci_Printout = []
        while counter1 != 9:
            igrac = igrac[:-1]
            Igraci_Printout.append(igrac)
            counter1 += 1
            if counter1 == 9:
                break   
            igrac = LeaderboardPage.Lista_Igraca.readline()
            if igrac == '':
                while counter1 != 9:
                    Igraci_Printout.append('')
                    counter1 += 1

        self.igrac_class = igrac

        return Igraci_Printout

    def configure_leaderboard(self, Igraci_Printout):
            self.board1.config(text = Igraci_Printout[0])
            self.board2.config(text = Igraci_Printout[1])
            self.board3.config(text = Igraci_Printout[2])
            self.board4.config(text = Igraci_Printout[3])
            self.board5.config(text = Igraci_Printout[4])
            self.board6.config(text = Igraci_Printout[5])
            self.board7.config(text = Igraci_Printout[6])
            self.board8.config(text = Igraci_Printout[7])
            self.board9.config(text = Igraci_Printout[8])

    def previous_page(self):
        if not(self.br_stranice == 0 
            or self.num_igraca_class < 9 
            or os.path.getsize('Lista_Igraca.txt') == 0):

            self.br_stranice -= 1
            LeaderboardPage.Lista_Igraca.seek(self.marker[self.br_stranice]) 
            self.configure_leaderboard(self.leaderboard_creation())
        
    def next_page(self):
        if not(self.igrac_class == '' 
            or self.num_igraca_class < 9 
            or os.path.getsize('Lista_Igraca.txt') == 0 
            or ((self.br_stranice+1) * 9 == self.num_igraca_class)):

            self.br_stranice += 1
            self.configure_leaderboard(self.leaderboard_creation())

    def write_to_leaderboard(name, wins, losses):

        if not os.path.isfile('Lista_Igraca.txt'):
            Lista_Igraca = open('Lista_Igraca.txt', 'x')
            Lista_Igraca.close()
        
        Lista_Igraca = open('Lista_Igraca.txt', 'r')
        num_igraca = sum(1 for line in Lista_Igraca)
        Lista_Igraca.close() 

        fajl_unos = str(f'{num_igraca+1}.\t{name}\t{wins}\t{losses}\n')
        
        Lista_Igraca = open("Lista_Igraca.txt", "a")
        Lista_Igraca.write(str(fajl_unos))
        Lista_Igraca.close()

        LeaderboardPage.num_igraca_class += 1


app = MultiPage()
app.mainloop()
Cewu00
  • 138
  • 9
  • This question has far too much code that seems unnecessary to represent the problem in the question. – Bryan Oakley May 26 '21 at 20:27
  • @BryanOakley I have deleted a lot of the stuff that is redundant from the first Class `MainMenu`. I'm not really sure what I should remove from the second one `LeaderboardPage` since that class is the main problem. A lot of the code is also tkinter gui placement. – Cewu00 May 26 '21 at 20:37
  • in your MainMenu : `self.parent = parent` and your Leaderboard. you need refernces to your tk.Tk. add to this `parent=None` and import the other classes – bangKok May 26 '21 at 20:37
  • @JoeMo I don't understand. That line is not present anywhere in the code? Would this potentially mess up anything else I have. I have copied this: [link](https://stackoverflow.com/questions/7546050/switch-between-two-frames-in-tkinter) to make multiple pages. I removed it because there was too much code. – Cewu00 May 26 '21 at 20:41
  • you need references to your `tk` class. You write in the __init__ (parent) . but you don't declare it. You haven't a reference, and i think this is the reason why you get attribut errors. I tried to run this code, but it doesn't work for me, so i would say that is the reason. but i can be wrong – bangKok May 26 '21 at 20:48
  • 1
    You've removed critical pieces of the code -- how you create an instance of `LeaderboardPage` -- and left in a bunch of unnecessary code. For example, is it really necessary to have all 10 labels to answer your question, or would a page with a single label work just as well _for the purposes of the question_? – Bryan Oakley May 26 '21 at 20:54
  • now i understand nothing .. (???) .. this link you posted is about switching frames. I would suggest make a new question. I'm confused hehe – bangKok May 26 '21 at 21:03
  • @JoeMo Sorry, I have completly edited the code, I hope It will be more clear now. It also compiles, just that the .txt file is empty. – Cewu00 May 26 '21 at 21:19
  • 1
    I recommend you read some of the questions and answers linked to from this answer: https://stackoverflow.com/a/7557028/7432 – Bryan Oakley May 26 '21 at 21:19
  • @BryanOakley Wow, I didn't even notice that. Thank you! – Cewu00 May 26 '21 at 21:21

1 Answers1

0

so you can try to do this with classes (there are smarter methods), to show you about refernces

import tkinter as tk


class MultiPage(tk.Tk):
    def __init__(self, parent=None, *args, **kwargs):                           # init your stuff / tk win = none
        tk.Tk.__init__(self, parent, *args, **kwargs)
        self.geometry("600x600")                                                # window options

        self.parent = parent

        self.border = tk.Frame(self)                                            # border frame
        self.border.pack(expand="yes", fill="both")

        self.mainmenu = MainMenu(self)                                          # import classes
        self.leaderboard = LeaderboardPage(self)

        self.mainmenu.frame_main.pack(side="top", fill="x", ipady="30")         # place your widgets (althought from other classes)
        self.leaderboard.leader.pack(side="left", fill="y", ipadx=30)


class MainMenu(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.parent = parent

        self.frame_main = tk.Frame(self.parent.border, bg="black")              # parent border to you main (you needn't this name border)


class LeaderboardPage(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.parent = parent

        self.leader = tk.Frame(self.parent.border, bg="red")
        

if __name__ == '__main__':                                                          # run app
    MultiPage()
    tk.mainloop()
bangKok
  • 332
  • 2
  • 13
  • Thank you for your time and answer, but I solved it already by following the link that Brayan Oakley added in the comment. I will delete the question since there is already an answer to my problem. Thank you non the less. – Cewu00 May 26 '21 at 21:57
  • i would`t delete it. maybe it helps other guys – bangKok May 26 '21 at 22:01