2

I look here. I can split my page (frame) into two file. For example, this is my first file: main.py

from Tkinter import *
from halsatu import *
class Biasa(Tk):
    def __init__(self, *args, **kwargs):
        Tk.__init__(self, *args, **kwargs)
        container = Frame(self)
        container.pack(expand=True)

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

        self.frames = {}

        for F in (StartPage, PageOne, PageTwo):
            frame = F(container, self)
            frame.grid(row=0, column=0, sticky='news')
            self.frames[F] = frame
        self.show_frame(StartPage)
    def show_frame(self, c):
        frame = self.frames[c]
        frame.tkraise()

class StartPage(Frame):
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        label = Label(self, text='Ini halaman Awal')
        label.pack()

        button = Button(self, text='ke Halaman 1',
            command=lambda: controller.show_frame(PageOne))
        button.pack()
        button2 = Button(self, text='ke Hal. 2',
            command=lambda: controller.show_frame(PageTwo))
        button2.pack()

class PageTwo(Frame):
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        label = Label(self, text='Sekarang \nIni halaman Dua lho..')
        label.pack()

        button = Button(self, text='ke Halaman 1',
            command=lambda: controller.show_frame(PageOne))
        button.pack()
        button2 = Button(self, text='ke Hal. Awal',
            command=lambda: controller.show_frame(StartPage))
        button2.pack()



if __name__ == '__main__':
    app = Biasa()
    app.mainloop()

Then this is my halsatu.py:

from Tkinter import *
class PageOne(Frame):
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        label = Label(self, text='Kalau yang Ini halaman Satuuuuuuuuuuuuuuuuuu')
        label.pack()

        button = Button(self, text='ke Halaman Awal',
            command=lambda: controller.show_frame(StartPage))
        button.pack()
        button2 = Button(self, text='ke Hal. 2',
            command=lambda: controller.show_frame(PageTwo))
        button2.pack()

That code can run. But when I go to pageone, I can't go back to StartPage again. How to split so many pages (frames) into separate files?

Community
  • 1
  • 1
recobayu
  • 581
  • 4
  • 6
  • Are you getting any error? – Anand S Kumar Jul 09 '15 at 02:54
  • yes. When I go to PageOne, and then I click the first button, this error appear: Exception in Tkinter callback Traceback (most recent call last): File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1489, in __call__ return self.func(*args) File "/home/muktyas/Dropbox/py/tk/150709oop/0914/halsatu.py", line 10, in command=lambda: controller.show_frame(StartPage)) NameError: global name 'StartPage' is not defined – recobayu Jul 09 '15 at 05:13
  • Yea I thought so, `StartPage` or `PageTwo` is not imported in your `halsatu.py` so they would not be accessible – Anand S Kumar Jul 09 '15 at 05:54
  • whether the code is in one file or several is irrelevant. What you want to do doesn't depend on how many files you use. – Bryan Oakley Jul 09 '15 at 10:11

1 Answers1

1

You are already passing in a controller to PageOne, so that can be the mechanism to raise pages. My recommendation is to make it possible to reference the pages by name rather than by class, and then give the controller a method that accepts the name and raises that page. This way your pages don't have to import each other, making for a looser coupling.

It would look something like this:

class Biasa(Tk):
    ...
    def show_page(self, page_name):
        for F in self.frames:
            if F.__name__ == page_name:
                self.show_frame(F)
                return

class PageOne(Frame):
    def __init__(self, parent, controller):
        ...
        button = Button(..., command=lambda: controller.show_page("StartPage"))
        ...
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685