0

I want each tab to come from it's own class (classes are in their own files - I am just testing the first one for now).

Here is what I tried:

tab1.py

from Tkinter import *
import Tkinter as tk

class Tab(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        fr = Frame(self).pack()
        Label(fr, text="one", bg='red', bd=2).pack()
        Label(fr, text="two", bg='yellow', bd=2).pack()

if __name__ == '__main__':
    root = Tk()
    frame = Frame(root).pack()
    Tab(frame)
    Button(frame, text='only if class', command=root.destroy).pack()
    mainloop()

noteBook.py

from Tkinter import *
from ttk import *
from tab1 import Tab

root = Tk()
note = Notebook(root)

main_frame = Frame(note)
button1 = Button(main_frame, text='test').pack()

#tab1 = Tab(note)
tab1 = Frame(note)
tab2 = Frame(note)
tab3 = Frame(note)
Tab(tab1)
Button(tab1, text='Exit', command=root.destroy).pack()

note.add(tab1, text = "Tab One", compound=TOP)
note.add(tab2, text = "Tab Two")
note.add(tab3, text = "Tab Three")
note.pack()
root.mainloop()
exit()

run with:

python2.7 noteBook.py

The problem is that the content of tab1.py does not appear within the first tab, it instead appears within the frame that contains the whole noteBook.

Also when running tab1.py directly with python2.7 noteBook.py I need it to behave properly meaning from what it has now it should show just the tab with an extra button from the if __name___... part.

I have come accros multiple examples but only found one that was what I want but it had no working solution and it was for python3 - I would like python2. python3 question with no working answer Thanks.

Touten
  • 190
  • 12

2 Answers2

1

The problem is this line of code:

fr = Frame(self).pack()

When you do the above, fr is None because .pack() returns None (because x().y() returns the value of y()). Later, you do this:

Label(fr, text="one", bg='red', bd=2).pack()

Since fr is None, the label is created in the root window.

Unrelated to the problem, here's some advice: you are creating too many frames. You don't need fr inside of Tab, and you don't need tab1, tab2, or tab3

Here's all you need for Tab:

class Tab(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master, background="pink")
        Label(self, text="one", bg='red', bd=2).pack()
        Label(self, text="two", bg='yellow', bd=2).pack()

To add it to the notebook, you just need two lines:

tab1 = Tab(note)
note.add(tab1, text = "Tab One", compound=TOP)
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • It succeeds at inserting the tab where it should go within the noteBook when run with `python2.7 noteBook.py` but it breaks `python2.7 tab1.py`: when I run the file `tab1.py` directly, the tab does not display properly, the 2 labels within the `Tab` class do not display. – Touten Aug 24 '17 at 04:14
  • HI Bryan, I have checked out some of your other posts on Tkinter and it made many things clearer. Thanks. – Touten Aug 24 '17 at 06:21
0

This works perfectly and just for fun I've illustrated the populating of tabs 2 and 3 althought I just reused the same class for simplicity here. The goal was to be able to run the tabs directly to view them alone during developpement without having to run the whole thing every time.

noteBook.py

from Tkinter import *
from ttk import *
from tab1 import Tab

root = Tk()
note = Notebook(root)

main_frame = Frame(note)
button1 = Button(main_frame, text='test').pack()

tab1 = Frame(note)
tab2 = Frame(note)
tab3 = Frame(note)
Tab(tab1)
Tab(tab2)
Tab(tab3)
Button(tab1, text='Exit', command=root.destroy).pack()

note.add(tab1, text = "Tab One", compound=TOP)
note.add(tab2, text = "Tab Two")
note.add(tab3, text = "Tab Three")
note.pack()
root.mainloop()
exit()

tab1.py

import Tkinter as tk

class Tab(tk.Frame):
    def __init__(self, parent_widget):
        tk.Frame.__init__(self, parent_widget)
        self.fr = tk.Frame(parent_widget, width=200, height=200, bg='pink', bd=2)
        tk.Label(self.fr, text="one", bg='red', bd=2).pack()
        tk.Label(self.fr, text="two", bg='yellow', bd=2).pack()
        self.fr.pack() # this packing must be done after 2 above packings

if __name__ == '__main__':
    root = tk.Tk() # the app window
    main_frame = tk.Frame(root, height=200, width=200, bg='blue', bd=2) # main frame
    Tab(main_frame) # instatiate Tab(), sending main_frame as the parent_widget
    tk.Button(main_frame, text='only if class', command=root.destroy).pack()
    main_frame.pack() # display main frame on window
    tk.mainloop()
Touten
  • 190
  • 12