Tkinter grid manager cutting off buttons - python-2.7

I have the following layout:
btnReset = Button(self.upperButtonFrame, text = "Reset", width = 12, command=self.__parent.reset)
btnReset.grid(row=0, column=0, sticky="W", pady=5)
btnRender = Button(self.upperButtonFrame, text = "Render", width = 9, command = self.render)
btnRender.grid(row=0, column=1, pady=5)
self.bScattered = Radiobutton(self.upperButtonFrame, text="Backscattered", variable=self.plotType, value=1).grid(row=1, column=0, sticky="W")
self.depolarized = Radiobutton(self.upperButtonFrame, text="Depolarized", variable=self.plotType, value=2).grid(row=2, column=0, sticky="W")
self.rng = Label(self.upperButtonFrame, text="Step").grid(row=3, column=0, sticky="W")
self.e = Entry(self.upperButtonFrame).grid(row=3,column=1)
self.to = Label(self.upperButtonFrame, text="to").grid(row=3, column=2)
self.e2 = Entry(self.upperButtonFrame).grid(row=3,column=3)
The problem is my third row looks like:
Instead of evenly spacing the 4 widgets I'm trying to place. How can I fix grid manager cutting off the last two and evenly space them on the screen?
EDIT: Here's a minimal example of my problem, running it should reproduce the results shown above
from Tkinter import Label, Toplevel, Frame, Button, IntVar, \
BOTH, BOTTOM, Radiobutton, Entry, TOP, Tk
CHILDWIDTH = 200
CHILDHEIGHT = 325
class ToolsWindow(Toplevel):
def __init__(self, root):
Toplevel.__init__(self, root)
self.__root = root
self.plotType = IntVar()
self.title("Tools")
self.geometry('%dx%d+%d+%d' % (CHILDWIDTH, CHILDHEIGHT,0, 0))
#self.resizable(width=FALSE, height=FALSE)
self.protocol("WM_DELETE_WINDOW", ToolsWindow.ignore)
self.container = Frame(self, background="red")
self.container.pack(side=TOP, fill=BOTH, expand=True )
self.coordinateFrame = Frame(self.container, background="green", width=50, height=50)
self.coordinateFrame.config(highlightthickness=1) # create a small border around the frame
self.coordinateFrame.config(highlightbackground="grey")
self.coordinateFrame.pack(side=BOTTOM, fill=BOTH, expand=False)
#staticmethod
def ignore():
pass
def setupToolBarButtons(self):
self.upperButtonFrame = Frame(self.container, background="blue") # upper button frame holding text buttons
self.upperButtonFrame.pack(side=TOP)
btnReset = Button(self.upperButtonFrame, text = "Reset", width = 12, command=self.render)
btnReset.grid(row=0, column=0, sticky="w")
btnRender = Button(self.upperButtonFrame, text = "Render", width = 9, command = self.render)
btnRender.grid(row=0, column=1, sticky="w")
self.bScattered = Radiobutton(self.upperButtonFrame, text="Backscattered",
variable=self.plotType, value=1).grid(row=1, column=0, sticky="w")
self.depolarized = Radiobutton(self.upperButtonFrame, text="Depolarized",
variable=self.plotType, value=2).grid(row=2, column=0, sticky="w")
self.rng = Label(self.upperButtonFrame, text="Step")
self.rng.grid(row=3, column=0, sticky="w")
self.e = Entry(self.upperButtonFrame, width=8)
self.e.grid(row=3, column=1, sticky="w")
self.to = Label(self.upperButtonFrame, text="to")
self.to.grid(row=3, column=2, sticky="w")
self.e2 = Entry(self.upperButtonFrame, width=8)
self.e2.grid(row=3, column=3, sticky="w")
def render(self):
pass
root = Tk()
tool = ToolsWindow(root)
tool.setupToolBarButtons()
root.mainloop()

The slightly modified program posted below renders properly, so it must be something in the code you did not post that is causing the problem. Are you limiting the size of the root window's, geometry anywhere? I do not know what you mean by "evenly spaced" but you can use the width parameter on most widgets to increase the size.
from Tkinter import *
class TestIt(object):
def __init__(self, top):
self.upperButtonFrame=top
btnReset = Button(self.upperButtonFrame, text = "Reset", width = 12)
btnReset.grid(row=0, column=0, sticky="W", pady=5)
btnRender = Button(self.upperButtonFrame, text = "Render", width = 9)
btnRender.grid(row=0, column=1, pady=5)
self.bScattered = Radiobutton(self.upperButtonFrame, text="Backscattered").grid(row=1, column=0
self.depolarized = Radiobutton(self.upperButtonFrame, text="Depolarized").grid(row=2, column=0,
self.rng = Label(self.upperButtonFrame, text="Step").grid(row=3, column=0, sticky="e")
self.e = Entry(self.upperButtonFrame).grid(row=3,column=1)
self.to = Label(self.upperButtonFrame, text="to").grid(row=3, column=2, sticky="e")
self.e2 = Entry(self.upperButtonFrame).grid(row=3,column=3)
top = Tk()
TI=TestIt(top)
top.mainloop()

Related

Tkinter grid in Gender option

How we set the grid for gender so that they will be close to 2 columns only.
I want gender(label), male and female(options) are packed into 2 columns.
Here is my code...
from Tkinter import *
root = Tk()
root.geometry('500x500')
root.title('Registration Form')
head = Frame(root)
entry = Frame(root)
head.pack()
entry.pack()
var = StringVar()
heading = Label(head,text='Registration Form',font='Helvetica 25 bold',pady=10).pack()
name_label = Label(entry,text='Name ',font='Helvetica 10 bold',pady=5)
name_entry = Entry(entry,width=30, font='Helvetica 10')
email_label = Label(entry,text='Email ',font='Helvetica 10 bold',pady=5)
email_entry = Entry(entry,width=30, font='Helvetica 10')
mob_label = Label(entry,text='Mobile ',font='Helvetica 10 bold',pady=5)
mob_entry = Entry(entry,width=30, font='Helvetica 10')
gender_label = Label(entry,text='Gender ',font='Helvetica 10 bold',pady=5)
male = Radiobutton(entry,text='Male',variable=var,value='male')
female = Radiobutton(entry,text='Female',variable=var,value='female')
name_label.grid(row=1, column=1)
name_entry.grid(row=1, column=2)
email_label.grid(row=2, column=1)
email_entry.grid(row=2, column=2)
mob_label.grid(row=3, column=1)
mob_entry.grid(row=3, column=2)
gender_label.grid(row=4, column=1)
male.grid(row=4,column=2, sticky="nsew")
female.grid(row=4,column=2,sticky="nsew")
root.mainloop()
Put male or female in next column and use columnspan=2 for Entry
from tkinter import *
root = Tk()
name_label = Label(root, text='Name')
name_entry = Entry(root)
gender_label = Label(root, text='Gender')
male = Radiobutton(root, text='Male')
female = Radiobutton(root, text='Female')
name_label.grid(row=1, column=1)
name_entry.grid(row=1, column=2, columnspan=2)
gender_label.grid(row=4, column=1)
male.grid(row=4, column=2, sticky="nsew")
female.grid(row=4, column=3, sticky="nsew")
root.mainloop()
See on effbot.org: The Tkinter Grid Geometry Manager

Unable to navigate to the next frame in the window using TKinter

I am trying to navigate to the next frame on which new buttons or new labels will be displayed. I mean frame1 should disappear when user clicks any button of the four buttons and frame2 should appear.But the below code does not work.
from Tkinter import *
import tkFileDialog
from PIL import ImageTk, Image
root = Tk()
#my_widget = Widget-name (its container window, ** its configuration options)
def callback():
path = tkFileDialog.askopenfilename()
print path
def create_widgets_in_first_frame():
first_window_label1 = Label(root, text="Analysis of Machine Learning Methods using Titanic Disaster Dataset",justify=CENTER,font=("Helvetica", 20,"bold")).place(x=200,y=20)
first_window_label5 = Label(root, text="Choose your Method:",justify=LEFT,font=("Helvetica", 15,"italic")).place(x=20,y=180)
first_window_label2 = Label(root, text="Upload your Titanic datasets .csv extension here:",justify=LEFT,font=("Helvetica", 15,"italic")).place(x=20,y=60)
first_window_label3 = Label(root, text="Training dataset ->",justify=LEFT,font=("Helvetica", 12)).place(x=50,y=100)
training_data_path = StringVar()
first_window_entry1 = Entry(root, textvariable=training_data_path).place(x=350,y=100)
first_window_button1 = Button(root, text="Browse",command=lambda:training_data_path.set(tkFileDialog.askopenfilename())).place(x=550,y=100)
first_window_label4 = Label(root, text="Testing dataset ->",justify=LEFT,font=("Helvetica", 12)).place(x=50,y=140)
testing_data_path = StringVar()
first_window_entry2 = Entry(root, textvariable=testing_data_path).place(x=350,y=140)
first_window_button2 = Button(root, text="Browse",command=lambda:testing_data_path.set(tkFileDialog.askopenfilename())).place(x=550,y=140)
first_window_button3 = Button(root, text="Decision Tree",font=("Helvetica", 15))
first_window_button3.place(x=50,y=220)
first_window_button3.bind('<Button-1>', call_second_frame_on_top)
first_window_button4 = Button(root, text="Random Forests",font=("Helvetica", 15))
first_window_button4.place(x=350,y=220)
first_window_button4.bind('<Button-1>', call_second_frame_on_top)
first_window_button5 = Button(root, text="Logistic Regression",font=("Helvetica", 15))
first_window_button5.place(x=650,y=220)
first_window_button5.bind('<Button-1>', call_second_frame_on_top)
first_window_button6 = Button(root, text="Analysis",font=("Helvetica", 15))
first_window_button6.place(x=1000,y=220)
first_window_button6.bind('<Button-1>', call_second_frame_on_top)
def create_widgets_in_second_frame():
second_window_label6 = Label(root, text="Decision Trees",justify=CENTER,font=("Helvetica", 20,"bold")).place(x=200,y=20)
print "graph is below"
def call_second_frame_on_top(event):
first_frame.grid_forget()
second_frame.grid(column=0, row=0, padx=20, pady=5)
window_width = 1300
window_heigth = 700
first_frame=Frame(root, width=window_width, height=window_heigth)
first_frame['borderwidth'] = 2
first_frame['relief'] = 'sunken'
first_frame.grid(column=0, row=0, padx=20, pady=5)
second_frame=Frame(root, width=window_width, height=window_heigth)
second_frame['borderwidth'] = 2
second_frame['relief'] = 'sunken'
second_frame.grid(column=0, row=0, padx=20, pady=5)
create_widgets_in_second_frame()
create_widgets_in_first_frame()
second_frame.grid_forget()
#root.minsize(width=1300, height=700)
#root.configure(background='lavender')
root.mainloop()
The problem is that you put all the widgets into root which is the whole window, so when you forget the frame, you forget nothing, as nothing is in the frame.
Just change the root to first_frame
Here is a working code:
from Tkinter import *
import tkFileDialog
from PIL import ImageTk, Image
root = Tk()
#my_widget = Widget-name (its container window, ** its configuration options)
def callback():
path = tkFileDialog.askopenfilename()
print path
def create_widgets_in_first_frame():
first_window_label1 = Label(first_frame, text="Analysis of Machine Learning Methods using Titanic Disaster Dataset",justify=CENTER,font=("Helvetica", 20,"bold")).place(x=200,y=20)
first_window_label5 = Label(first_frame, text="Choose your Method:",justify=LEFT,font=("Helvetica", 15,"italic")).place(x=20,y=180)
first_window_label2 = Label(first_frame, text="Upload your Titanic datasets .csv extension here:",justify=LEFT,font=("Helvetica", 15,"italic")).place(x=20,y=60)
first_window_label3 = Label(first_frame, text="Training dataset ->",justify=LEFT,font=("Helvetica", 12)).place(x=50,y=100)
training_data_path = StringVar()
first_window_entry1 = Entry(first_frame, textvariable=training_data_path).place(x=350,y=100)
first_window_button1 = Button(first_frame, text="Browse",command=lambda:training_data_path.set(tkFileDialog.askopenfilename())).place(x=550,y=100)
first_window_label4 = Label(first_frame, text="Testing dataset ->",justify=LEFT,font=("Helvetica", 12)).place(x=50,y=140)
testing_data_path = StringVar()
first_window_entry2 = Entry(first_frame, textvariable=testing_data_path).place(x=350,y=140)
first_window_button2 = Button(first_frame, text="Browse",command=lambda:testing_data_path.set(tkFileDialog.askopenfilename())).place(x=550,y=140)
first_window_button3 = Button(first_frame, text="Decision Tree",font=("Helvetica", 15))
first_window_button3.place(x=50,y=220)
first_window_button3.bind('<Button-1>', call_second_frame_on_top)
first_window_button4 = Button(first_frame, text="Random Forests",font=("Helvetica", 15))
first_window_button4.place(x=350,y=220)
first_window_button4.bind('<Button-1>', call_second_frame_on_top)
first_window_button5 = Button(first_frame, text="Logistic Regression",font=("Helvetica", 15))
first_window_button5.place(x=650,y=220)
first_window_button5.bind('<Button-1>', call_second_frame_on_top)
first_window_button6 = Button(first_frame, text="Analysis",font=("Helvetica", 15))
first_window_button6.place(x=1000,y=220)
first_window_button6.bind('<Button-1>', call_second_frame_on_top)
def create_widgets_in_second_frame():
second_window_label6 = Label(root, text="Decision Trees",justify=CENTER,font=("Helvetica", 20,"bold")).place(x=200,y=20)
print "graph is below"
def call_second_frame_on_top(event):
first_frame.grid_forget()
second_frame.grid(column=0, row=0, padx=20, pady=5)
window_width = 1300
window_heigth = 700
first_frame=Frame(root, width=window_width, height=window_heigth)
first_frame['borderwidth'] = 2
first_frame['relief'] = 'sunken'
first_frame.grid(column=0, row=0, padx=20, pady=5)
second_frame=Frame(root, width=window_width, height=window_heigth)
second_frame['borderwidth'] = 2
second_frame['relief'] = 'sunken'
second_frame.grid(column=0, row=0, padx=20, pady=5)
create_widgets_in_second_frame()
create_widgets_in_first_frame()
second_frame.grid_forget()
#root.minsize(width=1300, height=700)
#root.configure(background='lavender')
root.mainloop()
Note, that the label you get when you click any buttons is still in the main root so you will have to put that into the second_frame, or wherever you wish.

Linking a FuncAnimation() with a Button in Python 2.7

I am trying to start a graph (which is it's getting data from serial port) on a button's click. I had tried the following code but was not successful. I am new to python. Please help me in guiding were I am wrong.
I am using Python 2.7 with Tkinter
Thanks in advance
import serial
import Tkinter as tk
import ttk
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import figureCanvasTkAgg
import matplotlib.animation as animation
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
import tkFileDialog
x = []
adc_data = []
f = plt.Figure(figsize = (9,5), dpi = 100)
ax = f.add_subplot(111)
def select(self):
self.BaudRate = self.Baud.get()
self.COMPort = self.COM.get()
self.ser = serial.Serial(port = self.COMPort, baudrate = self.BaudRate,bytesize = serial.EIGHTBITS, stopbits = serial.STOPBITS_ONE, parity = serial.PARITY_NONE)
self.ser.close()
self.ser.open()
self.ser.flushInput();
self.ser.flushOutput();
def quit_(self):
self.ser.close()
def animate_(i):
self.ser.write(str(chr(250)))
data = self.ser.read(1)
data1 = self.ser.read(1)
LSB = ord(data)
MSB = ord(data1)
x.append(LSB)
adc_data.append(MSB) #adding data to list
plt.pause(.00001)
ax.clear()
ax.plot(x,adc_data)
def animate_button(self):
ani = animation.FuncAnimation(f, animate_,interval=1000)
class ADC_Ref_Data(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_geometry(self, '900x600+200+150')
tk.Tk.wm_title(self, "ADC Reference")
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 = {}
frame = StartPage(container, self)
self.frames[StartPage] = frame
frame.grid(row=0, column=0, sticky = "nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
self.button = ttk.Button(self, text="Stop", state = 'disable',
command=lambda: quit_(self))
self.button.place(relx = 0.97, rely = 0.95, height = 30 , width = 80, anchor = 'se')
button2 = ttk.Button(self, text="Select",
command = lambda:select(self))
button2.place(relx = 0.97, rely = 0.016, height = 30 , width = 80, anchor = 'ne')
button4 = ttk.Button(self, text="Start",
command=lambda: animate_button(self))
button4.place(relx = 0.03, rely = 0.95, height = 30 , width = 80 , anchor = 'sw')
canvas = FigureCanvasTkAgg(f, self)
canvas.show()
canvas.get_tk_widget().place(relx = 0.5, rely = 0.48, relwidth = 1, relheight = 0.8, anchor = 'center' )
app = ADC_Ref_Data()
app.mainloop()
I got success in getting my plot to start on button click.
To get my code working I just need to add a simple line in it which is as follow:
def animate_button(self):
ani = animation.FuncAnimation(f, animate_,frames = 10, interval=1000)
f.canvas.show()
I know this is an old question, but for future travelers: There are a couple functions that are not documented that you can use to control the animation. See this answer for an example of start, stop and pause.

How to expand widgets size in a frame with respect to other frames in Tkinter (Help on:Tkinter grid management)

Using Tkinter i have created 5 frames, each containing
frame0 - label,Entry box and a button(Enter)
frame1 - label and list box at the left side
frame2 - 2 buttons(select & unselect) at the center
frame3 - label and listbox at the right side
frame4 - 2 buttons(done & clear)
----------------------------------------
| frame0 |
----------------------------------------
| | | |
| frame1 | frame2 | frame3 |
| | | |
----------------------------------------
| frame4 |
----------------------------------------
This is my code:
from Tkinter import *
def toplevelwin():
def clear():
return
def select():
return
def unselect():
return
def done():
return
def enter():
return
window = Toplevel()
frame0 = Frame(window)
frame0.grid(row=0, column=0, sticky=W, padx=5, pady=5, columnspan=2)
frame0.grid_columnconfigure(1,weight=2)
lblentry = Label(frame0, text="Entery Box:")
lblentry.grid(row=0, column=0, sticky=W)
entrybx = Entry(frame0)
entrybx.grid(row=1,column=0,sticky=N+S+E+W, columnspan=2)
entrybt = Button(frame0, text=' Enter ', command=enter)
entrybt.grid(row=1,column=2,sticky=N+W, padx=3)
frame1 = Frame(window)
frame1.grid(row=1, column=0, sticky=E+W, padx=5, pady=5)
lblshow_lst = Label(frame1, text="List Box 1:")
lblshow_lst.grid(row=0,sticky=W)
show_lst = Listbox(frame1)
show_lst.grid(row=1,sticky=W)
frame2 = Frame(window)
frame2.grid(row=1, column=1, sticky=W)
frame2.grid_columnconfigure(1,weight=1)
selbtn = Button(frame2, text='Select', command=select)
selbtn.grid(row=0, padx=5, sticky=E+W)
selbtn.grid_columnconfigure(1,weight=1)
uselbtn = Button(frame2, text='Unselect', command=unselect)
uselbtn.grid(row=1, padx=5, sticky=E+W)
uselbtn.grid_columnconfigure(1,weight=1)
frame3 = Frame(window)
frame3.grid(row=1, column=2, sticky=W, padx=5, pady=5)
lblsel_lst = Label(frame3, text="List Box 2:")
lblsel_lst.grid(row=0,sticky=W)
sel_lst = Listbox(frame3)
sel_lst.grid(row=1, column=0, sticky=W)
frame4 = Frame(window)
frame4.grid(row=2, column=0, sticky=E, padx=5, pady=5)
Button(frame4, text=' Done ', command=done).grid(row=0, column=0, padx=7 ,pady=2)
Button(frame4, text='Clear', command=clear).grid(row=0,column=1, padx=7,pady=2)
window.wait_window(window)
root = Tk()
toplevelwin()
root.mainloop()
And this is how my window looks now:
My Question is:
How do i expand frame0 uptill frame3. ie, i want the entry box to extend till frame3's end having the button(enter) to its right side as it is.
And i want the bottom frame's button(done and clear) to be placed on the right side of the window
Tries:
i tried to increase the size of the entry widget, which in turn pushed frame2 and frame3 to the right side.
used sticky=N+S+W+E, which pushed it to the center of the window
also did tried sticky=W for the bottom frame containing 2 buttons. They moved to the center but not right
When using grid, to make a widget capable of expanding or shrinking, you need to
set its sticky parameter and set its grid cell's weight. Each column and each row
of a grid has a weight.
By default all column and row weights are 0, which mean they
will shrink to the smallest valid size.
To make it expand in the east-west direction, increase its column weight with
grid_columnconfigure.
To make it expand in the north-south direction, increase its row weight with
grid_rowconfigure.
So, for frame0,
Use columnspan=3 to make frame0 span 3 columns.
Use sticky='WE' to make frame0 stick to both the west and east sides of
its cell.
Use frame0.grid_columnconfigure(0, weight=1) to increase the grid cell's weight to 1.
For frame4,
frame4 = Frame(window)
frame4.grid(row=2, column=0, sticky='E', padx=5, pady=5, columnspan=3)
would work by making frame4 stick to the east side if its cell. Note that without a weight, frame4 shrinks too; it just shrinks while sticking to the east side, so the buttons it contains end up on the right.
If you want to make frame4 span the entire space from west to east as shown in your diagram, then use
frame4.grid(row=2, column=0, sticky='WE', padx=5, pady=5, columnspan=3)
frame4.grid_columnconfigure(0, weight=1)
Button(frame4, text=' Done ', command=done).grid(
row=0, column=0, padx=7, pady=2, sticky='E')
Button(frame4, text='Clear', command=clear).grid(
row=0, column=1, padx=7, pady=2, sticky='E')
from Tkinter import *
def toplevelwin():
def clear(): return
select = unselect = done = enter = clear
window = Toplevel()
frame0 = Frame(window)
frame0.grid(row=0, column=0, sticky='WE', padx=5, pady=5, columnspan=3)
frame0.grid_columnconfigure(0, weight=1)
lblentry = Label(frame0, text="Entry Box:")
lblentry.grid(row=0, column=0, sticky='W')
entrybx = Entry(frame0)
entrybx.grid(row=1, column=0, sticky='NSEW', columnspan=2)
entrybt = Button(frame0, text=' Enter ', command=enter)
entrybt.grid(row=1, column=2, sticky='NW', padx=3)
frame1 = Frame(window)
frame1.grid(row=1, column=0, sticky='EW', padx=5, pady=5)
lblshow_lst = Label(frame1, text="List Box 1:")
lblshow_lst.grid(row=0, sticky='W')
show_lst = Listbox(frame1)
show_lst.grid(row=1, sticky='W')
frame2 = Frame(window)
frame2.grid(row=1, column=1, sticky='W')
selbtn = Button(frame2, text='Select', command=select)
selbtn.grid(row=0, padx=5, sticky='EW')
uselbtn = Button(frame2, text='Unselect', command=unselect)
uselbtn.grid(row=1, padx=5, sticky='EW')
frame3 = Frame(window)
frame3.grid(row=1, column=2, sticky='W', padx=5, pady=5)
lblsel_lst = Label(frame3, text="List Box 2:")
lblsel_lst.grid(row=0, sticky='W')
sel_lst = Listbox(frame3)
sel_lst.grid(row=1, column=0, sticky='W')
frame4 = Frame(window)
frame4.grid(row=2, column=0, sticky='WE', padx=5, pady=5, columnspan=3)
frame4.grid_columnconfigure(0, weight=1)
Button(frame4, text=' Done ', command=done).grid(
row=0, column=0, padx=7, pady=2, sticky='E')
Button(frame4, text='Clear', command=clear).grid(
row=0, column=1, padx=7, pady=2, sticky='E')
window.wait_window(window)
root = Tk()
toplevelwin()
root.mainloop()
You don't need the frames (except for the buttons at the bottom).
Juste make your widgets like that:
entrybx = Entry(window)
entrybx.grid(row=0,column=0,sticky=N+S+E+W, columnspan=2) # columnspan= 3 better?
Use sticky=W when you want the widget on the left side of the column sticky=W +E for center, and sticky=E for right.
For the buttons at the bottom, don't forget columnspan:
frame4 = Frame(window)
frame4.grid(row=2, column=0, sticky=E, padx=5, pady=5, columnspan=3)
Button(frame4, text=' Done ', command=done).grid(row=0, column=0, padx=7 ,pady=2, sticky=E)
Button(frame4, text='Clear', command=clear).grid(row=0,column=1, padx=7,pady=2, sticky=E)

Tkinter's class.__init__() executes widget functions defined in it

I am writing a GUI for my application using Tkinter. I am using class to describe the whole structure, as described here. For some reason this program runs commands bounded to buttons (even though one of buttons is disabled) on start-up and doesn't react on same buttons afterwards. Please see my code below.
from Tkinter import *
from new_plot_main import PlotClass
class MainWindow:
def __init__(self, master):
Frame(master).grid()
self.main_check = [NoneType, NoneType, NoneType, NoneType]
self.scope_check = [NoneType, NoneType, NoneType, NoneType]
self.main_check[0] = Checkbutton(master, text="Lines")
self.main_check[1] = Checkbutton(master, text="Errors")
self.main_check[2] = Checkbutton(master, text="Upstream Snr")
self.main_check[3] = Checkbutton(master, text="Downstream Snr")
self.scope_check[0] = Checkbutton(master, text="Lines")
self.scope_check[1] = Checkbutton(master, text="Errors")
self.scope_check[2] = Checkbutton(master, text="Upstream Snr")
self.scope_check[3] = Checkbutton(master, text="Downstream Snr")
self.stats_check = Checkbutton(master, text="Enable statistics") # Statistics trigger
self.csi_check = Checkbutton(master, text="Enable CSI") # CSI calculation trigger
self.scope_range = Entry(master, width=15).grid(row=4, column=3) # To specify scope range
self.lines_entry = Entry(master, width=15).grid(row=6, column=1) # Lines to analyze
self.save_to_pdf_button = Button(master,
text="Save to PDF",
state=DISABLED,
width=10)
self.plot_button = Button(master, text="Plot", width=10, command=self.plot_action())
self.set_button = Button(master,
text="Set", state=DISABLED,
width=10, command=self.scope_action()) # Button to apply range from scope_range
#------Setting coordinates via grid--------
Label(master, text="Main", font=("Helvetica", 10, "bold")).grid(row=0, column=0, sticky=SW)
Label(master, text="Scope", font=("Helvetica", 10, "bold")).grid(row=0, column=1, sticky=SW)
Label(master, text="Options", font=("Helvetica", 10, "bold")).grid(row=0, column=3, sticky=SW)
Label(master, text="Lines to plot").grid(row=6, column=0, sticky=E)
Label(master, text="Set scope").grid(row=3, column=3, sticky=S)
self.stats_check.grid(row=1, column=3, sticky=W)
self.stats_check.select()
self.csi_check.grid(row=2, column=3, sticky=W)
self.csi_check.select()
self.save_to_pdf_button.grid(row=6, column=4, sticky=E)
self.plot_button.grid(row=6, column=2, sticky=W)
self.set_button.grid(row=4, column=4, sticky=W)
for i in xrange(0, 4):
self.main_check[i].grid(row=i+1, column=0, sticky=W)
self.scope_check[i].grid(row=i+1, column=1, sticky=W)
self.main_check[i].select()
self.scope_check[i].select()
def plot_action(self):
# plot = PlotClass()
# self.top = Toplevel()
print "Potatoes"
def scope_action(self):
# self.bot = Toplevel()
print "Banana"
def handler():
"""
Exiting GUI and stopping all processes, when system exit button is pressed.
"""
root.quit()
root.destroy()
root = Tk()
root.wm_title("Plot tool [new]")
app = MainWindow(root)
root.protocol("WM_DELETE_WINDOW", handler)
root.mainloop()
This code outputs Potatoes Banana upon execution.
You need to use just the function, not the function result. Instead of:
self.plot_button = Button(master, text="Plot", width=10,
command=self.plot_action())
and
self.set_button = Button(master, text="Set", state=DISABLED,
width=10, command=self.scope_action())
use:
self.plot_button = Button(master, text="Plot", width=10,
command=self.plot_action)
and
self.set_button = Button(master, text="Set", state=DISABLED,
width=10, command=self.scope_action)
That way the commands will be called only when the button is pressed.