Hector
Hector

Reputation: 285

Problems Remains inserting two different classes within the same frame into a notebook using Tkinter and Python

yesterday I was having a problem inserting two different classes into a notebook. unfortunately the problem still remains. You can find it following the link below:

Problems inserting two different classes within the same frame into a notebook using Tkinter and Python

I have followed the proposals, I Modified the code removing the button (unnecessary) which retrieved the values from the calculation. Now I have putted an entry instead (which doesn't work by the way), and also removed the unnecessary imports and so on. Even though, the script does not work, neither inserting the classes into the frame within the notebook. Hope you can help me!

Thanks in advance

Héctor

Here is the code:

from Tkinter import *
import Tkinter as tk
import ttk 
import tkFont
import tkMessageBox
import sys
import math

def defocus(event):
    event.widget.master.focus_set()

root = tk.Tk()
root.title("Autana")

f= tkFont.Font(family="verdana", size=12,weight=tkFont.BOLD)
f2= tkFont.Font(family="Times", size=20, weight=tkFont.BOLD)

c1= 'PeachPuff2'

notebook = ttk.Notebook(root)
notebook.pack(fill='both', expand=True)
notebook.pressed_index = None

ContainerOne = ttk.Frame(notebook);
ContainerOne.pack(fill='both', expand=True);

notebook.add(ContainerOne, text='Standard Reliability')

canvas1 = tk.Canvas(ContainerOne, width=950, height=450,bg=c1)
scroll = ttk.Scrollbar(ContainerOne, command=canvas1.yview)
canvas1.config(yscrollcommand=scroll.set, scrollregion=(0,0,100,1000))
canvas1.pack(side='left', fill='both', expand=True)
scroll.pack(side='right', fill='y')

frameOne = tk.Frame(canvas1, width=900, height=450)#,bg=c1,bd=22)
canvas1.create_window(630, 270, window=frameOne)

class MyListbox:
    def __init__(self, parent):
        self.parent = parent
        self.myData= (
                ["1", "Jhon Doe", "Madrid", "0341-672541", "6 SD"],
                ["5", "Kenji S.", "Tokyo", "0341-213212", "10 SD"])
        self.establishment()

    def combobox_handler(self, event):
        current = self.combobox.current()
        self.entNumber.delete(0, 'end')
        self.entName.delete(0, 'end')
        self.entCity.delete(0, 'end')
        self.entTel.delete(0, 'end')
        self.entAddress.delete(0, 'end')

        self.entNumber.insert('end', self.myData[current][0])
        self.entName.insert('end', self.myData[current][1])
        self.entCity.insert('end', self.myData[current][2])
        self.entTel.insert('end', self.myData[current][3])
        self.entAddress.insert('end', self.myData[current][4])

    def establishment(self):
        mainFrame = ttk.Frame(self.parent)
        mainFrame.pack(fill='both', expand='yes')

        fr_left = ttk.Frame(mainFrame)
        fr_left.pack(fill='both', expand='yes', side='left')

        names = [person[1] for person in self.myData]
        self.combobox = ttk.Combobox(fr_left, values=names)
        self.combobox.bind('<<ComboboxSelected>>', self.combobox_handler)
        self.combobox.pack()
        self.combobox.set("Data People")

        fr_right = ttk.Frame(mainFrame)
        fr_right.pack(fill='both', expand='yes', side='right')

        fr_up = ttk.Frame(fr_right)
        fr_up.pack(side='top', expand='yes')

        ttk.Label(fr_up, text='List Number').grid(row=0, column=0, sticky='w')
        self.entNumber = ttk.Entry(fr_up)
        self.entNumber.grid(row=0, column=1)

        ttk.Label(fr_up, text='Name').grid(row=1, column=0, sticky='w')
        self.entName = ttk.Entry(fr_up)
        self.entName.grid(row=1, column=1)

        ttk.Label(fr_up, text='City').grid(row=2, column=0, sticky='w')
        self.entCity = ttk.Entry(fr_up)
        self.entCity.grid(row=2, column=1)

        ttk.Label(fr_up, text='No. Tel').grid(row=3, column=0, sticky='w')
        self.entTel = ttk.Entry(fr_up)
        self.entTel.grid(row=3, column=1)

        ttk.Label(fr_up, text='Address').grid(row=4, column=0, sticky='w')
        self.entAddress = ttk.Entry(fr_up)
        self.entAddress.grid(row=4, column=1)


class Calculation:

    def __init__(self, parent):
        self.parent = parent
        self.Value1()
        self.Value2()
        self.Result()

        ttk.Label(self.parent,text='Num 1').grid(column=2, row=5, sticky='w', pady=3)
        ttk.Label(self.parent,text='Num 2').grid(column=2, row=6, sticky='w', pady=3)
        ttk.Label(self.parent,text='Result').grid(column=9,row=9, sticky='w', pady=3)

        self.msg = Label(self.parent,text='Sum of 2 number')
        self.msg.grid(row=3,column=1,columnspan=2)

        self.entry = ttk.Entry(text='Calculate',width=8,command=self.Calc)
        self.entry.grid(row=9,column=2,padx=2,pady=3)

    def Value1(self):
        self.field1 = ttk.Combobox(self.parent)
        self.field1['values'] = ('5', '6', '7')
        self.field1.grid(column=3, row=5)

    def Value2(self):
        self.field2 = ttk.Combobox(self.parent)
        self.field2['values'] = ('1', '2', '3')
        self.field2.grid(column=3, row=6)

    def Result(self):
        self.entry = StringVar()
        self.entry = ttk.Entry(self.parent, textvariable = self.entry)
        self.entry.grid(column=3, row=9)

    def Calc(self):
        self.entry.delete(0, 'end')
        try:
           value = int(self.field1.get()) + int(self.field2.get())
        except ValueError:
            self.entry.insert(0, 'Input numbers.')
        else:
            self.entry.insert(0, str(value))

if __name__ == '__main__':
    stepOne = ttk.LabelFrame(frameOne, text=" 1. Select People: ")
    stepOne.grid(row=0, column=5, sticky='nsew', \
             padx=5, pady=5, ipadx=5, ipady=5)

    stepTwo = ttk.LabelFrame(frameOne, text=" 2. Calculation : ")
    stepTwo.grid(row=7, column=5, sticky='w', \
             padx=5, pady=5, ipadx=5, ipady=5)

    app = MyListbox(stepOne)
    app2 = Calculation (stepOne)
    root.mainloop()

Upvotes: 1

Views: 548

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 385940

You've got way too many bugs in this code for us to help you. Let me give you some advice since you're obviously struggling: Don't try to build your whole app at once. Focus on one part at a time, get it right, and then move on.

For example, start over with your app and create the main window and the notebook, and nothing else. Get that part working. Create a dummy frame for your two notebook tabs just to prove that you have the notebook working and you understand how to add tabs. Don't do anything else until this simple program works, resizes, starts and stops like you expect. Give every widget you create a distinctive background color so that you can visually see each widget.

For example:

import Tkinter as tk
import ttk

root = tk.Tk()
notebook = ttk.Notebook(root)
notebook.pack(fill="both", expand=True)

tab1 = tk.Frame(notebook, background="red")
tab2 = tk.Frame(notebook, background="green")

notebook.add(tab1, text="Tab 1")
notebook.add(tab2, text="Tab 2")

root.mainloop()

Let me emphasize: don't do anything else until you have that working and understand what the code is doing

Once you are satisfied with that, you can now focus on one of the tabs. Each tab starts with a frame, so create a function that creates just the frame. Have this function return the frame rather than pack or grid the frame in the parent. As a rule of thumb you should never have a function or class pack/grid itself in its parent, because it makes your code hard to understand and modify. Make each frame a self-contained thing, and let the code that creates it decide how to lay it out. Believe me, it is much easier to write a GUI this way.

For example:

def tab1(parent):
    frame = tk.Frame(parent, background="pink")

    return frame

Then modify your code to be like this:

import Tkinter as tk
import ttk

<put your definition of tab1 here...>

root = tk.Tk()
notebook = ttk.Notebook(root)
notebook.pack(fill="both", expand=True)

tab1 = tab1(notebook)
tab2 = tk.Frame(notebook, background="green")

notebook.add(tab1, text="Tab 1")
notebook.add(tab2, text="Tab 2")

root.mainloop()

Ok, now stop, run that code, and make sure you understand what happened. Is it all still working? Now, in the blank line in tab1, you can add all the widgets for this container. You can pack or grid them inside the frame, you don't have to pass all of those up. You only pass the container up to the caller. Eventually you can learn how to create a subclass of tk.Frame instead of using a function, but don't worry about that now. If you follow this style of coding, switching to an object oriented style in the future will be pretty painless.

Continue on working like this, building up one piece at a time. Stop as often as you can and run the code, making sure it still resizes properly and is laid out the way you want. Tackle each section separately, and eventually it will all work wonderfully together.

Upvotes: 2

Related Questions