2

For my computer class at school we have to create software for a movie kiosk. I have a class which outlines the basis for every screen, then from that class I make separate classes for each individual screen. When the user clicks a button I want a bunch of the widgets on the screen to update to display the relevant information. Here is the class for the screen that displays the movies.

class BrowseMovies(tk.Frame):

    def switchMovie():
        global movNum
        movNum += 1
        print(movNum)
        #update the gui

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

        backGroundPicture = ImageTk.PhotoImage(Image.open("Background.jpg"))
        backGroundLabel = tk.Label(self, image=backGroundPicture, borderwidth=0)
        backGroundLabel.image = backGroundPicture
        backGroundLabel.place(x=0, y=0, anchor=tk.NW)

        moviesLabel = tk.Label(self, text="Movies", font=("Verdana", 48), bg="#001f33", fg="red")
        moviesLabel.place(relx=0.5, rely=0, anchor=tk.N)

        middleFrame = tk.Frame(self)
        middleFrame.place(relx=0.5, rely=0.5, anchor=tk.CENTER, height=470, width=750)

        movieImage = ImageTk.PhotoImage(Image.open(moviePosterLinks[movNum]))
        movieImageLabel = tk.Label(middleFrame, image=movieImage, borderwidth=0)
        movieImageLabel.image = movieImage
        movieImageLabel.place(x=0, rely=0.5, anchor=tk.W)

        movieTitleLabel = tk.Label(middleFrame, text=movieTitles[movNum], font=("Verdana", 20), borderwidth=0)
        movieTitleLabel.place(x=317, y=0, anchor=tk.NW)

        movieRatingsLabel = tk.Label(middleFrame, text="Rotten Tomatoes Rating: " + movieRatings[movNum], font=("Verdana", 20), borderwidth=0)
        movieRatingsLabel.place(x=317, y=30, anchor=tk.NW)

        movieRestrictionsLabel = tk.Label(middleFrame, text=movieRestrictions[movNum], font=("Verdana", 20), borderwidth=0)
        movieRestrictionsLabel.place(x=317, y=60, anchor=tk.NW)

        movieDirectorsLabel = tk.Label(middleFrame, text="Director: " + movieDirectors[movNum], font=("Verdana", 20), borderwidth=0)
        movieDirectorsLabel.place(x=317, y=90, anchor=tk.NW)

        movieGenresLabel = tk.Label(middleFrame, text="Genre: " + movieGenres[movNum], font=("Verdana", 20), borderwidth=0)
        movieGenresLabel.place(x=317, y=120, anchor=tk.NW)

        returnButton = tk.Button(self, text="Return to Main Menu", bg="#4db8ff", fg="black",
                           command=lambda: controller.show_frame(StartPage))
        returnButton.place(relx=1, rely=1, anchor=tk.SE)

        changeButton = tk.Button(self, text="Switch to next movie", command=lambda: BrowseMovies.switchMovie(controller))
        changeButton.place(relx=1, rely=0.5, anchor=tk.E)

When I call the switchMovies function, the movNum variables (which represents the current selected movie) does update, however the gui stays idle, How could I make it update to display the new information?

********/****Edit****/********

Now adding the code for template "Window" class as suggested.

class Window(tk.Tk):

def __init__(self):
    tk.Tk.__init__(self)

    self.title("Movie Kiosk")
    self.attributes("-fullscreen", True)
    self.resizable(width=False, height=False)

    container = tk.Frame(self)
    container.pack(side="top", fill="both", expand=1)
    container.grid_rowconfigure(0, weight=1)
    container.grid_columnconfigure(0, weight=1)

    self.frames = {}

    for f in (StartPage, CheckOut, BrowseMovies, BrowseSnacks):
        frame = f(container, self)
        self.frames[f] = frame
        frame.grid(row=0, column=0, sticky="nsew")

    self.show_frame(StartPage)

2 Answers2

0

I suggest using simpler names, without the redundant 'movie' and 'Label'. But in any case, since the Labels can be set from movie num, define a method to update label, and use it for the initial setting also. I assume that movNum is initialized to 0 before the code you posted. In other words,

class BrowseMovies(tk.Frame):
    ...
    def __init__(self, parent, controller):
        ...
        title = tk.Label(middleFrame, font=("Verdana", 20), borderwidth=0)
        ...
        self.update_labels()  # after all labels defined
        ...
    def update_labels(self):
        self.title['text'] = movieTitles[movNum]
        ... # similar  for other titles

Then also call update_labels when movNum is changed.

Terry Jan Reedy
  • 18,414
  • 3
  • 40
  • 52
  • I think I get what you are saying but it wasn't able to fix the problem, getting an error something along the lines of "object not have attribute...". Yes movNum was initialized to 0 in global space above. –  Feb 15 '16 at 05:41
0

This may be one of several things:

  1. It could depend on how you summon the GUI. Have you globalized all necessary variables? See this. I think you need to add global MovNum to the top of your __init__.
  2. Updating your GUI may require a dirty trick involving using root.update() after every process/method call.
  3. You could also try Tk.update().

This is just what I think is the problem based off of my experience with Tkinter. It can be hard to tell without seeing the rest of your code.

Best of luck, and happy coding!

Community
  • 1
  • 1
Joseph Farah
  • 2,463
  • 2
  • 25
  • 36
  • 1
    Thanks for pointing that out, I've now added global movNum add the top of my __init__ function. Will be adding the template class in an edit shortly, thanks. –  Feb 15 '16 at 05:43