Python: Tkinter active and deactive entry space with checkutton - python

I have a Entry space to import my data in Tkinter. I wish to active or deactive this space using a Checkbutton. When Checkbutton == 1, you can insert data, when Checkbutton == 0 the space became grey and you can not insert data
from Tkinter import *
import tkMessageBox
class MainWindow(Frame):
def __init__(self):
Frame.__init__(self)
self.master.title("input")
self.master.minsize(150, 50)
self.grid(sticky=E+W+N+S)
top=self.winfo_toplevel()
top.rowconfigure(0, weight=1)
top.columnconfigure(0, weight=1)
for i in range(1):self.rowconfigure(i, weight=1)
self.columnconfigure(1, weight=1)
self.label0 = Label(self, text="Data: ")
self.label0.grid(row=0, column=0, padx=2)
self.entry11 = Entry(self)
self.entry11.grid(row=0, column=1, pady=2, padx=2, sticky=E+W+N+S)
self.CheckVar_theta = IntVar()
self.check = Checkbutton(self, text="", variable=self.CheckVar_theta, onvalue = 0, offvalue = 1)
self.check.grid(row=0, column=3, pady=0, padx=0, sticky=E+W+N+S)
if __name__=="__main__":
d=MainWindow()
d.mainloop()

You need to do two things:
Make a function to change the state of the entrybox that will be called each time the checkbutton is clicked. It should look something like this:
def switch(self):
if self.CheckVar_theta.get():
self.entry11.config(state=DISABLED)
else:
self.entry11.config(state=NORMAL)
Assign the checkbutton's command parameter to that function:
self.check = Checkbutton(self, ..., command=self.switch)
In the end, your code will look like this:
from Tkinter import *
import tkMessageBox
class MainWindow(Frame):
def __init__(self):
Frame.__init__(self)
self.master.title("input")
self.master.minsize(150, 50)
self.grid(sticky=E+W+N+S)
top=self.winfo_toplevel()
top.rowconfigure(0, weight=1)
top.columnconfigure(0, weight=1)
for i in range(1):self.rowconfigure(i, weight=1)
self.columnconfigure(1, weight=1)
self.label0 = Label(self, text="Data: ")
self.label0.grid(row=0, column=0, padx=2)
self.entry11 = Entry(self)
self.entry11.grid(row=0, column=1, pady=2, padx=2, sticky=E+W+N+S)
self.CheckVar_theta = IntVar()
self.check = Checkbutton(self, text="", variable=self.CheckVar_theta,
onvalue = 0, offvalue = 1, command=self.switch)
self.check.grid(row=0, column=3, pady=0, padx=0, sticky=E+W+N+S)
def switch(self):
if self.CheckVar_theta.get():
self.entry11.config(state=DISABLED)
else:
self.entry11.config(state=NORMAL)
if __name__=="__main__":
d=MainWindow()
d.mainloop()

I think this should work:
from Tkinter import *
import tkMessageBox
class MainWindow(Frame):
def __init__(self):
Frame.__init__(self)
self.master.title("input")
self.master.minsize(150, 50)
self.grid(sticky=E+W+N+S)
top=self.winfo_toplevel()
top.rowconfigure(0, weight=1)
top.columnconfigure(0, weight=1)
for i in range(1):self.rowconfigure(i, weight=1)
self.columnconfigure(1, weight=1)
self.label0 = Label(self, text="Data: ")
self.label0.grid(row=0, column=0, padx=2)
self.entry11 = Entry(self)
self.entry11.grid(row=0, column=1, pady=2, padx=2, sticky=E+W+N+S)
self.CheckVar_theta = IntVar()
self.check = Checkbutton(self, text="", variable=self.CheckVar_theta, onvalue = 0, offvalue = 1)
self.check.grid(row=0, column=3, pady=0, padx=0, sticky=E+W+N+S)
self.update()
def update(self):
if self.CheckVar_theta.get() == 1:
self.entry11.config(state=NORMAL)
else:
self.entry11.config(state=DISABLED)
self.master.after(100, self.update)
if __name__=="__main__":
d=MainWindow()
d.mainloop()

Related

Is It possible to create multiple form fields in tkinter & python and then submit it to a out to an output textbox in a table column format

So my problem is that I want to create multiple entry fields like over 30, but every time I reformat it using .pack or .grid it keeps throwing off the formatting. is there a way to fit nearly 30 entry boxes on one window without using anything like SQLite? As we can see from this code, we have 4 fields, how would you go on with shrinking the boxes to put in more entry fields like over 30.
Secondly, I want to output all the typed data entry fields to the Listbox is there a way to add a table column to the list box to show a breakdown of each entry field.
The third is it possible to move the Listbox to another tab on the same window to show all entry fields that were typed in, if so how would you do so.
Here is my current code so far
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
from datetime import *
# Import Packages
import tkinter as tk
from tkinter import *
from tkinter import ttk
from tkinter.scrolledtext import *
import tkinter.filedialog
from tkcalendar import Calendar, DateEntry
from tkinter import messagebox
from tkintertable import TableCanvas, TableModel
from tkinter import ttk
# Database
#import sqlite3
import csv
window = Tk()
window.title("TESTTEST")
window.geometry("750x450")
window.config(background='black')
#style = ttk.Style(window)
#style.configure('lefttab.TNotebook', tabposition='wn',)
# TAB LAYOUT
#tab_control = ttk.Notebook(window,style='righttab.TNotebook')
#tab1 = ttk.Frame(tab_control)
#tab2 = ttk.Frame(tab_control)
#tab3 = ttk.Frame(tab_control)
#tab4 = ttk.Frame(tab_control)
#tab5 = ttk.Frame(tab_control)
#tab6 = ttk.Frame(tab_control)
# ADD TABS TO NOTEBOOK
#tab_control.add(tab1, text=f'{"Home":^20s}')
#tab_control.add(tab2, text=f'{"View":^20s}')
#tab_control.add(tab3, text=f'{"Search":^20s}')
#tab_control.add(tab4, text=f'{"Edit":^20s}')
#tab_control.add(tab5, text=f'{"Export":^20s}')
#tab_control.add(tab6, text=f'{"About ":^20s}')
#label1 = Label(tab1, text= 'Python RPA APP',padx=1, pady=1)
#label1.grid(column=0, row=0)
#label2 = Label(tab2, text= 'View',padx=5, pady=5)
#label2.grid(column=0, row=0)
#label3 = Label(tab3, text= 'Search',padx=5, pady=5)
#label3.grid(column=0, row=0)
#label4 = Label(tab4, text= 'Edit/Update',padx=5, pady=5)
#label4.grid(column=0, row=0)
#label5 = Label(tab5, text= 'Export',padx=5, pady=5)
#label5.grid(column=0, row=0)
#label6 = Label(tab6, text= 'About',padx=5, pady=5)
#label6.grid(column=0, row=0)
#tab_control.pack(expand=1, fill='both')
class Main(ttk.Frame):
def __init__(self, parent):
super().__init__()
self.parent = parent
self.punches_list = []
self.ent1 = tk.StringVar()
self.ent2 = tk.StringVar()
self.ent3 = tk.StringVar()
self.ent4 = tk.StringVar()
self.init_ui()
def init_ui(self):
f = ttk.Frame()
# ttk.Label(f, text = "Entry1").pack(side=TOP, anchor=NW)
## ttk.Label(f, text = "Entry1").pack(side=LEFT, padx=5, pady=5, anchor=NW)
## self.txTest = ttk.Entry(f,textvariable=self.ent).pack(fill=X, padx=5, expand=True, anchor=NW)
# ttk.Label(f, text = "Entry1").pack(side=TOP, anchor=NW)
# self.txTest1 = ttk.Entry(f, textvariable=self.ent2).pack(side=TOP, anchor=NW)
ttk.Label(f, text = "Entry1").pack(side=TOP, anchor=NW, fill=tk.BOTH, pady=5, padx=5, expand=0)
self.txTest1 = ttk.Entry(f, textvariable=self.ent1).pack(side=TOP, anchor=NW, fill=tk.BOTH, pady=5, padx=5, expand=0)
ttk.Label(f, text = "Entry2").pack(side=TOP, anchor=NW,fill=tk.BOTH, pady=5, padx=5, expand=0)
self.txTest2 = ttk.Entry(f, textvariable=self.ent2).pack(side=TOP, anchor=NW,fill=tk.BOTH, pady=5, padx=5, expand=0)
ttk.Label(f, text = "Entry3").pack(side=TOP, anchor=NW,fill=tk.BOTH, pady=5, padx=5, expand=0)
self.txTest3 = ttk.Entry(f, textvariable=self.ent3).pack(side=TOP, anchor=NW,fill=tk.BOTH, pady=5, padx=5, expand=0)
#tkinter.Label(window, text = "Username").grid(row = 0) #'username' is placed on position 00 (row - 0 and column - 0)
#tkinter.Entry(window).grid(row = 0, column = 1) # first input-field is placed on position 01 (row - 0 and column - 1)
ttk.Label(f, text = "Entry4").pack(side=TOP, anchor=NW,fill=tk.BOTH, pady=5, padx=5, expand=0)
self.txTest4 = ttk.Entry(f, textvariable=self.ent4).pack(side=TOP, anchor=NW,fill=tk.BOTH, pady=5, padx=5, expand=0)
self.lstItems = self.get_listbox(f, 140,140).pack(anchor=N)
w = ttk.Frame()
ttk.Button(w, text="Add",command=self.add_In).pack(side=TOP, anchor=NE)
ttk.Button(w, text="Clear", command=self.clear_Out).pack(side=TOP, anchor=NE)
ttk.Button(w, text="Close", command=self.on_close).pack(side=TOP, anchor=NE)
#f.pack(side=tk.RIGHT, fill=tk.BOTH, expand=1)
#w.pack(side=tk.RIGHT, fill=tk.BOTH, expand=1)
f.pack(side=tk.LEFT, fill=tk.BOTH, pady=5, padx=5, expand=1)
w.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
def add_In(self,):
#s = "IN {0:>30} {1}".format(str(datetime.now()), self.ent.get())
s = self.ent1.get()
self.set_list(s)
s = self.ent2.get()
self.set_list(s)
s = self.ent3.get()
self.set_list(s)
s = self.ent4.get()
self.set_list(s)
self.ent1.set('')
self.ent2.set('')
self.ent3.set('')
self.ent4.set('')
def clear_Out(self):
#s = "OUT {0:>29} {1}".format(str(datetime.now()), self.ent1.get())
#field_name.set('')
self.ent1.set('')
self.ent2.set('')
self.ent3.set('')
self.ent4.set('')
#self.set_list(s)
def set_list(self,s):
self.punches_list.append(s)
self.lstItems.delete(0, tk.END)
for i in self.punches_list:
self.lstItems.insert(tk.END, i)
def on_set(self):
self.check.set(1)
def on_close(self):
#self.destroy()
self.parent.on_exit()
def get_listbox(self, container, height=750, width=600):
sb = tk.Scrollbar(container,orient=tk.VERTICAL)
w = tk.Listbox(container,
relief=tk.GROOVE,
selectmode=tk.BROWSE,
height=height,
width=width,
background = 'white',
font='TkFixedFont',
yscrollcommand=sb.set,)
sb.config(command=w.yview)
w.pack(side=tk.LEFT,fill=tk.BOTH, expand =1)
sb.pack(fill=tk.Y, expand=1)
return w
class App(tk.Tk):
"""Start here"""
def __init__(self):
super().__init__()
self.protocol("WM_DELETE_WINDOW", self.on_exit)
self.set_style()
self.set_title()
Main(self,)
def set_style(self):
self.style = ttk.Style()
#('winnative', 'clam', 'alt', 'default', 'classic', 'vista', 'xpnative')
self.style.theme_use("vista") #change to your liking :)
def set_title(self):
s = "{0}".format('Employee Time-Clock')
self.title(s)
self.destroy()
def on_exit(self):
window.destroy()
#self.destroy()
#sys.exit()
#"""Close all"""
#if messagebox.askokcancel( self.title(), "Do you want to quit?", parent=self):
# self.destroy()
if __name__ == '__main__':
app = App()
app.mainloop()
Your code is a giant mess, brah ;D. What I gather from your question is that you need some kind of table. What I gather from your code is the table should have cells comprised of Label and Entry. You also want an interface to create entries. Below is an example of all of that. I don't really see anything to explain. It's just a bunch of Frame, Label, Entry and Button. The only real action is in Table. All that action is, is mathematically figuring out where to put the next Item. This is all really basic stuff.
import tkinter as tk
from tkinter import ttk
#the entire bottom row of the app.
#has a dependency on self.master.table ~ not good OOP
class EntryManager(tk.Frame):
def __init__(self, master, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
self.grid_columnconfigure(5, weight=1)
font='Helvetica 10 bold'
tk.Label(self, text='Label', font=font, width=5).grid(row=0, column=0, padx=2)
lbl = tk.Entry(self, width=10, font=font)
lbl.grid(row=0, column=1, padx=2)
tk.Label(self, text='Entry', font=font, width=5).grid(row=0, column=2, padx=2)
ent = tk.Entry(self, width=25, font=font)
ent.grid(row=0, column=3, padx=2)
tk.Button(self, text='add', font=font, command=lambda: self.master.table.addItem(lbl.get(), ent.get())).grid(row=0, column=4, padx=2, sticky='w')
tk.Label(self, text='rows', font=font, width=4).grid(row=0, column=5, padx=2, sticky='e')
r = tk.Entry(self, width=4, font=font)
r.insert('end', self.master.table.rows)
r.grid(row=0, column=6, padx=2)
tk.Label(self, text='cols', font=font, width=4).grid(row=0, column=7, padx=2)
c = tk.Entry(self, width=4, font=font)
c.insert('end', self.master.table.cols)
c.grid(row=0, column=8, padx=2)
tk.Button(self, text='set', font=font, command=lambda: self.master.table.setDims(r.get(), c.get())).grid(row=0, column=9, padx=2, sticky='e')
#generic scrollable frame
class ScrollFrame(tk.Frame):
def __init__(self, master, row=0, column=0, scrollspeed=.02, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
self.grid(row=row, column=column, sticky='nswe')
self.scrollspeed = scrollspeed
self.canvas = tk.Canvas(self, highlightthickness=0)
self.canvas.grid(column=0, row=0, sticky='nswe')
self.v_scroll = tk.Scrollbar(self, orient='vertical', command=self.canvas.yview)
self.v_scroll.grid(row=0, column=1, sticky='ns')
self.canvas.configure(yscrollcommand=self.v_scroll.set)
self.canvas.bind_all('<MouseWheel>', self.on_mousewheel)
self.frame = tk.Frame(self.canvas, height=0)
self.frame.grid_columnconfigure(0, weight=1)
self.frame.bind('<Configure>', lambda e:self.canvas.configure(scrollregion=self.canvas.bbox("all")))
self.canvas.create_window((0,0), window=self.frame, anchor="nw")
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
def on_mousewheel(self, event):
self.canvas.yview_moveto(self.v_scroll.get()[0]+((-event.delta/abs(event.delta))*self.scrollspeed))
#a table cell
class Item(tk.Frame):
#property
def value(self):
return self.__value.get()
#value.setter
def value(self, text):
self.__value.set(text)
def __init__(self, master, text, value, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
tk.Label(self, text=text, width=10, font='none 8 bold').grid(row=0, column=0, pady=5, padx=5)
self.__value = tk.StringVar(value=value)
tk.Entry(self, textvariable=self.__value, width=25).grid(row=0, column=1, pady=5, padx=5)
#the table
class Table(ScrollFrame):
def __init__(self, master, rows=15, cols=3, **kwargs):
ScrollFrame.__init__(self, master, **kwargs)
self.entries = []
self.rows = rows
self.cols = cols
def addItem(self, text, value):
if len(self.entries) < self.rows*self.cols:
self.entries.append(Item(self.frame, text, value))
self.entries[-1].grid(row=(len(self.entries)-1)%self.rows, column=(len(self.entries)-1)//self.rows)
def getItem(self, row, column):
return self.entries[self.rows*column+row].value
def setDims(self, rows, cols):
if rows.isnumeric():
self.rows = int(rows)
if cols.isnumeric():
self.cols = int(cols)
for ent in self.entries:
ent.grid_forget()
for i, ent in enumerate(self.entries):
if i < self.rows*self.cols:
ent.grid(row=i%self.rows, column=i//self.rows)
class App(tk.Tk):
WIDTH, HEIGHT, TITLE = 770, 465, 'Application'
def __init__(self):
tk.Tk.__init__(self)
ttk.Style().theme_use("vista")
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
self.table = Table(self, rows=20, cols=3)
self.table.grid(row=0, column=0, sticky='nswe')
EntryManager(self).grid(row=1, column=0, sticky='nswe', ipady=5)
#junk for testing
for i in range(12):
self.table.addItem(f'entry_{i}', f'data {i}')
if __name__ == '__main__':
app = App()
app.config(background='black')
app.title(App.TITLE)
app.geometry(f'{App.WIDTH}x{App.HEIGHT}')
#app.resizable(width=False, height=False)
app.mainloop()
Might as well dump the table keys in the table and see what happens. The sizes and alignments of things could use some work.

extra spaces between buttons in tkinter

I have implemented a code to make GUI using Tkinter and I'm new in this. The problem which I'm facing is that there is lots of spacing between two buttons in column 3 ( select object and play button).
I want to know that why this is happening.
my code is here:
from tkinter import Tk, Text, BOTH, W, N, E, S
from tkinter.ttk import Frame, Button, Label, Style
class Example(Frame):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.master.title("Nav Track app")
self.pack(fill=BOTH, expand=True)
self.style = Style()
self.style.theme_use("default")
self.columnconfigure(1, weight=1)
self.columnconfigure(3, pad=7)
self.rowconfigure(3, weight=1)
self.rowconfigure(5, pad=7)
lbl = Label(self, text="Keep your eyes on screen")
lbl.grid(sticky=W, pady=4, padx=5)
area = Text(self)
area.grid(row=1, column=0, columnspan=2, rowspan=5,
padx=8, sticky=E + W + S + N)
abtn = Button(self, text="Start Camera")
abtn.grid(row=1, column=3, padx=4)
cbtn = Button(self, text="Select Object")
cbtn.grid(row=2, column=3, padx=4, pady=4)
dbtn = Button(self, text="Play")
dbtn.grid(row=3, column=3, padx=4, pady=4)
hbtn = Button(self, text="Help")
hbtn.grid(row=7, column=0, padx=5)
obtn = Button(self, text="Exit")
obtn.grid(row=7, column=3)
def main():
root = Tk()
root.geometry("500x450+300+500")
app = Example()
root.mainloop()
if __name__ == '__main__':
main()

Clearing text area in Python ToDo-app GUI

I've already did a cool little CLI To-Do app in python, and now I'm trying to build a basic GUI around it. The main buttons, field in place, and yesterday I've figured out how to redirect the return string from my Todo class to the text area.
My problem now is how to clear the text area? Currently if I press the 'View button' it's continously redirecting the text without deleting the previous output. I've tried to create a function with
self.text.delete('1.0','end') + the function with the string output, but it's not working. Can you suggest me something? Thanks in advance!
import tkinter as tk
from tkinter import messagebox as mbox
from todo_app import ToDo, arguments
import sys
class ToDoGui:
def __init__(self, root):
self.t = ToDo()
self.root = root
self.mainframe = tk.Frame(self.root, bg="white")
self.mainframe.pack(fill=tk.BOTH, expand=True)
self.build_grid()
self.build_banner()
self.build_text_area()
self.build_buttons()
sys.stderr = TextRedirector(self.text, "stderr")
self.entry()
def build_grid(self):
self.mainframe.columnconfigure(0, weight=1)
self.mainframe.rowconfigure(0, weight=0)
self.mainframe.rowconfigure(1, weight=1)
self.mainframe.rowconfigure(0, weight=0)
def build_banner(self):
banner = tk.Label(
self.mainframe,
bg="orange",
text="PyKeep",
fg="green",
font=('Helvetica', 24)
)
banner.grid(
row=0, column=0,
sticky='ew',
padx=10, pady=10
)
def build_buttons(self):
buttons_frame = tk.Frame(self.mainframe)
buttons_frame.grid(row=3, column=0, sticky='nsew',
padx=10, pady=10)
buttons_frame.columnconfigure(0, weight=1)
buttons_frame.columnconfigure(1, weight=1)
buttons_frame.columnconfigure(2, weight=1)
buttons_frame.columnconfigure(3, weight=1)
buttons_frame.columnconfigure(4, weight=1)
self.clear_button = tk.Button(
buttons_frame,
text='Clear',
command=self.text.delete('0.0', tk.END)
)
self.view_button= tk.Button(
buttons_frame,
text='View list',
command=self.t.list_view
)
self.add_button = tk.Button(
buttons_frame,
text='Add task',
command=None
)
self.remove_button = tk.Button(
buttons_frame,
text='Remove task',
command=None
)
self.complete_button = tk.Button(
buttons_frame,
text='Complete task',
command=None
)
self.clear_button.grid(row=0, column=0, sticky='ew')
self.view_button.grid(row=0, column=1, sticky='ew')
self.add_button.grid(row=0, column=2, sticky='ew')
self.remove_button.grid(row=0, column=3, sticky='ew')
self.complete_button.grid(row=0, column=4, sticky='ew')
def entry(self):
entry_field = tk.Entry(self.mainframe, bd=2)
entry_field.grid(row=1, column=0, sticky='nwse', padx=10, pady=10)
entry_field.insert(0, 'Enter task OR number of a task')
entry_field.focus()
def build_text_area(self):
text_frame = tk.Text(self.mainframe, wrap="word")
text_frame.grid(row=2, column=0, sticky='nsew',
padx=10, pady=10)
text_frame.columnconfigure(0, weight=1)
text_frame.config(state=tk.DISABLED)
text_frame.tag_configure("stderr", foreground="#b22222")
self.text = text_frame
return self.text
class TextRedirector(object):
def __init__(self, widget, tag="stderr"):
self.widget = widget
self.tag = tag
def write(self, str):
self.widget.configure(state="normal")
self.widget.insert("end", str, (self.tag,))
self.widget.configure(state="disabled")
if __name__ == '__main__':
root = tk.Tk()
ToDoGui(root)
root.mainloop()
The contents you are trying to delete is not Text's contents. It's your Entry widget.
def entry(self):
entry_field = tk.Entry(self.mainframe, bd=2)
entry_field.grid(row=1, column=0, sticky='nwse', padx=10, pady=10)
entry_field.insert(0, 'Enter task OR number of a task')
entry_field.focus()
self.entry_field= entry_field #make entry widget class' object
#since there is only one row in common Entry, you need to only specify starting index
self.clear_button = tk.Button(..., command=lambda: self.entry_field.delete(0, tk.END)

Fill frame on window resize

When you enter a file name in the entry filed and click the "Open" button, the content will be displayed.
I want the Entry and Text widget to completely fill Frame3 (red) and continue to do so when the application window is resized. How do I achieve this?
This is my code:
from Tkinter import *
ALL = N+S+W+E
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master.rowconfigure(0, weight=1)
self.master.columnconfigure(0, weight=1)
self.grid(sticky=ALL)
def handler(event):
print("clicked at", event.x, event.y)
def show_entry_fields():
#print e1.get()
f=open(e1.get())
out_put=f.read()
l1=Label(f3, text=out_put,fg="purple").grid(row=5,column=2)
return out_put
def call_red():
out_put=show_entry_fields()
Label(f3, text=out_put,fg="red").grid(row=5,column=2)
def call_green():
out_put=show_entry_fields()
Label(f3, text=out_put,fg="green").grid(row=5,column=2)
def call_blue():
out_put=show_entry_fields()
Label(f3, text=out_put,fg="blue").grid(row=5,column=2)
def call_black():
out_put=show_entry_fields()
Label(f3, text=out_put,fg="black").grid(row=5,column=2)
for r in range(4):
self.rowconfigure(r, weight=1)
self.master.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
b1=Button(self, text="Red",command=call_red).grid(row=5, column=0, sticky=ALL)
self.columnconfigure(1, weight=1)
b2=Button(self, text="Blue",command=call_blue).grid(row=5, column=1, sticky=ALL)
self.columnconfigure(2, weight=1)
b3=Button(self, text="Green",command=call_green).grid(row=5, column=2, sticky=ALL)
self.columnconfigure(3, weight=1)
b4=Button(self, text="Black",command=call_black ).grid(row=5, column=3, sticky=ALL)
self.columnconfigure(4, weight=1)
b5=Button(self, text="Open",command=show_entry_fields).grid(row=5, column=4, sticky=ALL)
#------------------------------
f1 = Frame(self, bg="blue")
f1.grid(row=0, column=0, rowspan=2,columnspan=2, sticky=ALL)
f1.bind("<Button-1>", handler)
f1.focus()
f2 = Frame(self, bg="green")
f2.grid(row=2, column=0, rowspan=2,columnspan=2, sticky=ALL)
f2.bind("<Button-1>", handler)
f2.focus()
f3 = Frame(self, bg="red")
f3.grid(row=0, column=2, rowspan=4, columnspan=4, sticky=ALL)
l=Label(f3, text="Enter File Path:").grid(row=1)
e1 = Entry(f3)
e1.grid(row=1,column=2)
root = Tk()
app = Application(master=root)
app.mainloop()
You should assign a weight to the column and row in which you place the text:
f3.grid_columnconfigure(2, weight=1)
f3.grid_rowconfigure(5, weight=1)
This tells Tkinter that it should distribute any extra space to that row and column, which will make the cell grow upon resize.
You might want to add sticky=ALL to your e1 then too, so it resizes with the text below it.

Using Python and TKinter, how do I redraw the main screen

I have a program where the main window is divided into two sections each section has a collection of forms (simple label/input columns). The default is 4 of these columns in the first section and 2 in the second section. I would like the user to be able to change this ratio. I think I have all of the programming in place to do this, I just can't get the main window to redraw with the correct structure. Any help would be much appreciated. Thanks.
I like the simplicity and idea behind your example, however, I'm modifying some legacy code and don't have the time to rewrite my layouts as definitions. I tried to create a def that would simply do grid_columnconfig(), but that didn't work. I've reduced the code so that it looks like what I'm working with and it is also functional. If you change the variable 'max_pol_modules' it adjusts columns on the left versus columns on the right, so, I'm trying to change this variable through an interface widget and redraw.
from Tkinter import *
import tkFont
max_pol_modules = 3
max_bus_modules = 6 - max_pol_modules
tech_green = '#5E9732'
button_grey = '#666666'
grey = '#777777'
def config1():
global max_pol_modules, max_bus_modules
max_pol_modules = 1
max_bus_modules = 6 - max_pol_modules
# print max_bus_modules
# left_frame.update()
def config2():
global max_pol_modules, max_bus_modules
max_pol_modules = 2
max_bus_modules = 6 - max_pol_modules
# print max_bus_modules
def config3():
global max_pol_modules, max_bus_modules
max_pol_modules = 3
max_bus_modules = 6 - max_pol_modules
# print max_bus_modules
def config4():
global max_pol_modules, max_bus_modules
max_pol_modules = 4
max_bus_modules = 6 - max_pol_modules
# print max_bus_modules
def about():
box.showinfo("About GUI","GE Bus Converter and Point of Load GUI")
def bar(frame, row, span):
"create a bar to separate a section"
x = Frame(frame, relief=GROOVE, bd=2, width=86*(span+1), height=2)
x.grid(row=row, column=0, columnspan=10, pady=7, sticky=S+E)
x.grid_propagate(0)
def bar2(frame, row, span):
"create a bar to separate a section"
x = Frame(frame, relief=GROOVE, bd=2, width=86*(span+1), height=2)
x.grid(row=row, column=0, columnspan=10, pady=3, sticky=S+E)
x.grid_propagate(0)
def bar3(frame, row, span):
"create a bar to separate a section"
x = Frame(frame, relief=GROOVE, bd=2, width=100, height=2)
x.grid(row=row, column=0, columnspan=10, pady=7, sticky=S+E)
x.grid_propagate(0)
root = Tk()
menubar = Menu(root)
submenu=Menu(menubar,tearoff=0)
submenu2=Menu(submenu,tearoff=0)
submenu2.add_command(label="1 - 5", command=config1)
submenu2.add_command(label="2 - 4", command=config2)
submenu2.add_command(label="3 - 3", command=config3)
submenu2.add_command(label="4 - 2", command=config4)
submenu_help = Menu(submenu,tearoff=0)
submenu_help.add_command(label="About",command=about)
submenu.add_cascade(label="Change Configuration",menu=submenu2)
submenu.add_command(label="Exit", command=root.quit)
menubar.add_cascade(label="Settings",menu=submenu)
menubar.add_cascade(label="Help", menu=submenu_help)
# display the menu
root.config(menu=menubar)
entry_wid = 6
small_font = tkFont.Font(family='Arial', size=8, weight='bold')
lite_font = tkFont.Font(family='Arial', size=9)
large_font = tkFont.Font(family='Arial', size=9)
heading_font = tkFont.Font(family='Arial', size=10, weight='bold')
button_font = tkFont.Font(family='Arial', size=8, weight='bold')
root.option_add('*font', lite_font)
root.option_add('*background', '#C2C2C4')
root.option_add('*Label.font', small_font)
root.option_add('*Entry.background', 'white')
root.option_add('*Button.font', button_font)
root.option_add('*Button.background', button_grey)
root.option_add('*Button.foreground', 'yellow')
root.option_add('*Text.background', 'white')
root.option_add('*Text.font', small_font)
root.option_add('*ScrolledText.font', lite_font)
left_frame = Frame(root)
right_frame = Frame(root)
pol_frame = Frame(left_frame, bd=2, relief=SUNKEN)
x = Label(pol_frame, text="POL Address", anchor=E)
x.grid(row=0, column=0, sticky=E)
x = Label(pol_frame, text="Rtrim (Kohms)", anchor=E)
x.grid(row=1, column=0, sticky=E)
x = Label(pol_frame, text="Nominal Vout (V)", anchor=E)
x.grid(row=2, column=0, sticky=E)
bar2(pol_frame, 0, max_pol_modules)
module_address = []
module_i2c = []
module_status = []
module_resistor = []
module_vout_nominal = []
for i in range(max_pol_modules):
# Module ID and address
f = Frame(pol_frame)
x = Label(f, text=i+1)
x.grid(row=0, column=0)
v = StringVar()
x = Entry(f, textvariable=v, width=3, justify=CENTER)
x.grid(row=0, column=1)
f.grid(row=0, column=i+1, pady=8, padx=20)
module_address.append(v)
module_i2c.append("")
module_status.append(0)
# module resistor
v = StringVar()
x = Entry(pol_frame, textvariable=v, width=entry_wid, justify=CENTER)
f = lambda event, module=i: change_resistor_event(event, module)
g = lambda value, m=i, o=16: set_change(value, m, o)
x.bind("<KeyRelease>", f, "+")
x.bind("<KeyRelease>", g, "+")
x.bind("<FocusOut>", f, "+")
x.grid(row=1, column=i+1, pady=0)
module_resistor.append(v)
# module nominal vout
v = StringVar()
x = Label(pol_frame, textvariable=v, width=entry_wid-1,
relief=SUNKEN, bg='#DDDDDD', font=lite_font)
x.grid(row=2, column=i+1, pady=0)
module_vout_nominal.append(v)
bus_frame = Frame(left_frame, bd=2, relief=SUNKEN)
#x = Label(bus_frame, text="Module (address)", anchor=E)
#x.grid(row=0, column=max_pol_modules+1, sticky=E)
x = Label(bus_frame, text="Bus Conv Address", anchor=E)
x.grid(row=0, column=0, sticky=E)
config_bus = []
r = 0
#for i in range(max_pol_modules,max_pol_modules+max_bus_modules):
for i in range(max_bus_modules):
# Module ID and address
f = Frame(bus_frame)
x = Label(f, text=i+5)
x.grid(row=0, column=0)
v = StringVar()
x = Entry(f, textvariable=v, width=3, justify=CENTER)
x.grid(row=0, column=1)
f.grid(row=0, column=i+2, pady=8, padx=20)
module_address.append(v)
module_i2c.append("")
module_status.append(0)
bar2(bus_frame, r, max_bus_modules)
r += 1
# the measured values
measure_info = ["Vout (V)", "Iout (A)", "Vin (V)", "Temp (degC)"]
measures_bus = []
for mi in measure_info:
x = Label(bus_frame, text=mi, anchor=E)
x.grid(row=r, column=0, sticky=E)
m = []
for j in range(max_bus_modules):
v = StringVar()
x = Label(bus_frame, textvariable=v, width=entry_wid-1,
relief=SUNKEN, bg='#DDDDDD', font=lite_font)
x.grid(row=r, column=j+2)
m.append(v)
measures_bus.append(m)
r += 1
pol_frame.grid(row=0, column=0, sticky=N+W)
bus_frame.grid(row=0, column=1, sticky=N+W)
left_frame.grid(row=0, column=0, sticky=N)
right_frame.grid(row=0, column=1, sticky=N)
root.mainloop()
Edited Example where form[4] and form[5] need to be deleted.
import Tkinter as tk
class App(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.forms = []
self.toolbar = tk.Frame(self)
self.toolbar.pack(side="top", fill="x", expand=False)
button2 = tk.Button(self.toolbar, text="2 columns", command=self.layout2col)
button3 = tk.Button(self.toolbar, text="3 columns", command=self.layout3col)
button2.pack(side="left")
button3.pack(side="left")
self.forms_frame = tk.Frame(self, borderwidth=2, relief="groove")
self.forms_frame.pack(side="top", fill="both", expand="True", padx=2, pady=2)
for i in range(6):
frame = tk.LabelFrame(self.forms_frame, text="Form %s" % i)
self.forms.append(frame)
label = tk.Label(frame, text="Field %s" % i)
entry = tk.Entry(frame, width=20)
label.pack(side="left", fill="y")
entry.pack(side="left", fill="both", expand=True)
self.layout2col()
def layout3col(self):
self.forms[0].grid(column=0, row=0, padx=4, pady=2, sticky="ew")
self.forms[1].grid(column=0, row=1, padx=4, pady=2, sticky="ew")
self.forms[2].grid(column=1, row=0, padx=4, pady=2, sticky="ew")
self.forms[3].grid(column=1, row=1, padx=4, pady=2, sticky="ew")
self.forms[4].grid(column=2, row=0, padx=4, pady=2, sticky="ew")
self.forms[5].grid(column=2, row=1, padx=4, pady=2, sticky="ew")
self.forms_frame.grid_columnconfigure(0, weight=1)
self.forms_frame.grid_columnconfigure(1, weight=1)
self.forms_frame.grid_columnconfigure(2, weight=1)
def layout2col(self):
self.forms[0].grid(column=0, row=0, padx=4, pady=2, sticky="ew")
self.forms[1].grid(column=0, row=1, padx=4, pady=2, sticky="ew")
self.forms[2].grid(column=1, row=0, padx=4, pady=2, sticky="ew")
self.forms[3].grid(column=1, row=1, padx=4, pady=2, sticky="ew")
self.forms_frame.grid_columnconfigure(0, weight=1)
self.forms_frame.grid_columnconfigure(1, weight=1)
self.forms_frame.grid_columnconfigure(2, weight=0)
if __name__ == "__main__":
app = App()
app.mainloop()
Since you are using the grid geometry manager, you just need to use the grid method to place them in their new rows and columns. You may need to also call rowconfigure and/or columnconfigure to attach appropriate weights to the new rows and columns.
Here's a bit of a contrived example showing the general principle. It could be more efficient but hopefully it gives you a rough idea:
import Tkinter as tk
class App(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.forms = []
self.toolbar = tk.Frame(self)
self.toolbar.pack(side="top", fill="x", expand=False)
button2 = tk.Button(self.toolbar, text="2 columns", command=self.layout2col)
button3 = tk.Button(self.toolbar, text="3 columns", command=self.layout3col)
button2.pack(side="left")
button3.pack(side="left")
self.forms_frame = tk.Frame(self, borderwidth=2, relief="groove")
self.forms_frame.pack(side="top", fill="both", expand="True", padx=2, pady=2)
for i in range(6):
frame = tk.LabelFrame(self.forms_frame, text="Form %s" % i)
self.forms.append(frame)
label = tk.Label(frame, text="Field %s" % i)
entry = tk.Entry(frame, width=20)
label.pack(side="left", fill="y")
entry.pack(side="left", fill="both", expand=True)
self.layout2col()
def layout3col(self):
self.forms[0].grid(column=0, row=0, padx=4, pady=2, sticky="ew")
self.forms[1].grid(column=0, row=1, padx=4, pady=2, sticky="ew")
self.forms[2].grid(column=1, row=0, padx=4, pady=2, sticky="ew")
self.forms[3].grid(column=1, row=1, padx=4, pady=2, sticky="ew")
self.forms[4].grid(column=2, row=0, padx=4, pady=2, sticky="ew")
self.forms[5].grid(column=2, row=1, padx=4, pady=2, sticky="ew")
self.forms_frame.grid_columnconfigure(0, weight=1)
self.forms_frame.grid_columnconfigure(1, weight=1)
self.forms_frame.grid_columnconfigure(2, weight=1)
def layout2col(self):
self.forms[0].grid(column=0, row=0, padx=4, pady=2, sticky="ew")
self.forms[1].grid(column=0, row=1, padx=4, pady=2, sticky="ew")
self.forms[2].grid(column=0, row=2, padx=4, pady=2, sticky="ew")
self.forms[3].grid(column=1, row=0, padx=4, pady=2, sticky="ew")
self.forms[4].grid(column=1, row=1, padx=4, pady=2, sticky="ew")
self.forms[5].grid(column=1, row=2, padx=4, pady=2, sticky="ew")
self.forms_frame.grid_columnconfigure(0, weight=1)
self.forms_frame.grid_columnconfigure(1, weight=1)
self.forms_frame.grid_columnconfigure(2, weight=0)
if __name__ == "__main__":
app = App()
app.mainloop()
You've probably already tried this, but can you call update() on your root widget?
You might also need to pack() again, first.

Categories

Resources