I started a project where I want to script an application for my company to capture values of an iterative signal processing job.
I want to include the option to switch between different modules that require different parameters to test.
When I click on the buttons on the left I want the content of the data entry frame to change to a different set of Labels and Entry widgets. I tried to put the widgets for 'AAA' in a different class but I don't know how to initialize the class via button click so the widgets in the class get created/visible. I tried it with .lift() but that's ugly. I also want to keep the same 2 frames under the data entry frame, and the ScrolledText on the right, just working with the active module. Any ideas? Someone can push me in the right direction?
Oh yeah, and this is my first project apart from simple read->replace string-> scripts.
Here's the code:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import Tkinter as tk
import json
import tkFileDialog
import sys
import ScrolledText
from Tkinter import*
class testlogger(tk.Tk):
def __init__(self,parent):
tk.Tk.__init__(self,parent)
self.parent = parent
self.initialize()
def initialize(self):
self.grid()
#--------------------------------------------------------------------------------------
menubar = tk.Menu(self)
filemenu = tk.Menu(menubar, tearoff=0)
filemenu.add_command(label="New")
filemenu.add_command(label="Open", command=self.load_file)
filemenu.add_command(label="Save", command=self.safe_file)
filemenu.add_command(label="Save as...")
filemenu.add_command(label="Close")
filemenu.add_separator()
filemenu.add_command(label="Exit", command=self.quit)
menubar.add_cascade(label="File", menu=filemenu)
editmenu = tk.Menu(menubar, tearoff=0)
editmenu.add_command(label="Undo")
editmenu.add_separator()
editmenu.add_command(label="Cut")
editmenu.add_command(label="Copy")
editmenu.add_command(label="Paste")
editmenu.add_command(label="Delete")
editmenu.add_command(label="Select All")
menubar.add_cascade(label="Edit", menu=editmenu)
helpmenu = tk.Menu(menubar, tearoff=0)
helpmenu.add_command(label="Help Index")
helpmenu.add_command(label="About...")
menubar.add_cascade(label="Help", menu=helpmenu)
self.config(menu=menubar)
#--------------------------------------------------------------------------------------
treeFrame = tk.Frame(self)
treeFrame.grid(column=0, row=1, sticky='NW')
b1 = Button(treeFrame, text=u'AAA', command=self.AAAlift)
b1.pack(fill='x')
b2 = Button(treeFrame, text=u'RADON', command=self.radonlift)
b2.pack(fill='x')
b3 = Button(treeFrame, text=u'Adaptive Subtract')
b3.pack(fill='x')
b4 = Button(treeFrame, text=u'GMP')
b4.pack(fill='x')
#--------------------------------------------------------------------------------------
#
#
#
#--------------------------------------------------------------------------------------
self.enterData = tk.LabelFrame(self, text=" Data Entry ")
self.enterData.grid(column=1, row=1, columnspan=4, sticky='NW', \
padx=5, pady=5, ipadx=5, ipady=5)
titleAAA = tk.Label(self.enterData, text="AAA")
titleAAA.grid(row=1, columnspan=4, sticky='N', padx=5, pady=2)
self.freqInput = tk.StringVar()
self.freqInput2 = tk.StringVar()
self.thresInput = tk.StringVar()
self.widthInput = tk.StringVar()
self.minFreq = tk.Label(self.enterData, text="Minimum Frequency")
self.minFreq.grid(row=2, column=1, sticky='E', padx=5, pady=2)
minFreqData = tk.Entry(self.enterData, textvariable=self.freqInput)
minFreqData.grid(row=2, column=2, sticky='E', padx=5, pady=2)
self.maxFreq = tk.Label(self.enterData, text="Maximum Frequency")
self.maxFreq.grid(row=3, column=1, sticky='E', padx=5, pady=2)
maxFreqData = tk.Entry(self.enterData, textvariable=self.freqInput2)
maxFreqData.grid(row=3, column=2, sticky='E', padx=5, pady=2)
self.threshold = tk.Label(self.enterData, text="Threshold")
self.threshold.grid(row=2, column=3, sticky='E', padx=5, pady=2)
thresData = tk.Entry(self.enterData, textvariable=self.thresInput)
thresData.grid(row=2, column=4, sticky='E', padx=5, pady=2)
self.width = tk.Label(self.enterData, text="SpatialWidth")
self.width.grid(row=3, column=3, sticky='E', padx=5, pady=2)
widthData = tk.Entry(self.enterData, textvariable=self.widthInput)
widthData.grid(row=3, column=4, sticky='E', padx=5, pady=2)
self.valueList = [self.freqInput, self.freqInput2, self.thresInput, self.widthInput]
self.labelList = [self.minFreq, self.maxFreq, self.threshold, self.width]
enteredAAAData = []
#--------------------------------------------------------------------------------------
self.radon = LabelFrame(self, text=" Data Entry ")
self.radon.grid(column=1, row=1, columnspan=4, sticky='NW', \
padx=5, pady=5, ipadx=5, ipady=5)
titleRadon = Label(self.radon, text="Radon Fwd Transform")
titleRadon.grid(row=1, columnspan=4, sticky='N', padx=5, pady=2)
self.minMOInput = StringVar()
self.maxMOInput = StringVar()
self.offsetInput = StringVar()
self.numpInput = StringVar()
self.motypeInput = StringVar()
self.maxfreqInput = StringVar()
self.minMO = Label(self.radon, text="Minimum Moveout")
self.minMO.grid(row=2, column=1, sticky='E', padx=5, pady=2)
minMOData = Entry(self.radon, textvariable=self.minMOInput)
minMOData.grid(row=2, column=2, sticky='E', padx=5, pady=2)
self.maxMO = Label(self.radon, text="Maximum Moveout")
self.maxFreq.grid(row=3, column=1, sticky='E', padx=5, pady=2)
maxMOData = Entry(self.radon, textvariable=self.maxMOInput)
maxMOData.grid(row=3, column=2, sticky='E', padx=5, pady=2)
self.offset = Label(self.radon, text="Reference Offset")
self.offset.grid(row=2, column=3, sticky='E', padx=5, pady=2)
offsetData = Entry(self.radon, textvariable=self.offsetInput)
offsetData.grid(row=2, column=4, sticky='E', padx=5, pady=2)
self.numP = Label(self.radon, text="Number of P-Traces")
self.numP.grid(row=3, column=3, sticky='E', padx=5, pady=2)
numPData = Entry(self.radon, textvariable=self.numpInput)
numPData.grid(row=3, column=4, sticky='E', padx=5, pady=2)
self.motype = Label(self.radon, text="Moveout Type")
self.motype.grid(row=4, column=1, sticky='E', padx=5, pady=2)
motypeData = Entry(self.radon, textvariable=self.motypeInput)
motypeData.grid(row=4, column=2, sticky='E', padx=5, pady=2)
self.maxfreq = Label(self.radon, text="Maximum Frequency")
self.maxfreq.grid(row=4, column=3, sticky='E', padx=5, pady=2)
maxfreqData = Entry(self.radon, textvariable=self.maxfreqInput)
maxfreqData.grid(row=4, column=4, sticky='E', padx=5, pady=2)
self.valueList = [self.minMOInput, self.maxMOInput, self.offsetInput, self.numpInput, self.motypeInput, self.maxfreqInput]
self.labelList = [self.minMO, self.maxMO, self.offset, self.numP, self.motype, self.maxfreq]
enteredRadonData = []
#--------------------------------------------------------------------------------------
evalData = tk.Frame(self)
evalData.grid(column=1, row=2, sticky='NW', \
padx=5, pady=5, ipadx=5, ipady=5)
evalLabel = tk.Label(evalData, text="Evaluation")
evalLabel.grid(row=1, column=1, columnspan=3, sticky='N', padx=5, pady=2)
self.eval_state = tk.StringVar()
goodRadio = tk.Radiobutton(evalData, text="Good", variable=self.eval_state, value='Good')
goodRadio.grid(row=2, column=1, sticky='W', padx=5, pady=2)
badRadio = tk.Radiobutton(evalData, text="Bad", variable=self.eval_state, value='Bad')
badRadio.grid(row=2, column=2, sticky='W', padx=5, pady=2)
sameRadio = tk.Radiobutton(evalData, text="Same", variable=self.eval_state, value='Same')
sameRadio.grid(row=2, column=3, sticky='W', padx=5, pady=2)
qcDisp = tk.Label(evalData, text="QC Displays:")
qcDisp.grid(row=2,column=4, sticky='W', padx=10, pady=2)
self.checkB4 = tk.IntVar()
optionBefore = tk.Checkbutton(evalData, text="Before", variable=self.checkB4, onvalue=1, offvalue=0)
optionBefore.grid(row=1, column=5, sticky='W', padx=5, pady=2)
optionAfter = tk.Checkbutton(evalData, text="After", onvalue=1, offvalue=0)
optionAfter.grid(row=2, column=5, sticky='W', padx=5, pady=2)
optionDiff = tk.Checkbutton(evalData, text="Difference", onvalue=1, offvalue=0)
optionDiff.grid(row=3, column=5, sticky='W', padx=5, pady=2)
optionSpectrum = tk.Checkbutton(evalData, text="Frequency Spectrum", onvalue=1, offvalue=0)
optionSpectrum.grid(row=1, column=6, sticky='W', padx=5, pady=2)
optionAuto = tk.Checkbutton(evalData, text="Auto Correlation", onvalue=1, offvalue=0)
optionAuto.grid(row=2, column=6, sticky='W', padx=5, pady=2)
optionBanana = tk.Checkbutton(evalData, text="I'm a Banana", onvalue=1, offvalue=0)
optionBanana.grid(row=3, column=6, sticky='W', padx=5, pady=2)
#--------------------------------------------------------------------------------------
self.comment = tk.Text(self, height=5, bg='white')
self.comment.grid(column=1, row=3, sticky='NW', \
padx=5, pady=5, ipadx=5, ipady=5)
submit_b = tk.Button(self, text=u"Submit", command=self.enter_data)
submit_b.grid(column=1, row=4, sticky='NE')
#--------------------------------------------------------------------------------------
protocolFrame = tk.LabelFrame(self, text="Protocol")
protocolFrame.grid(row=1, column=2, rowspan=3, sticky='NW')
self.protocolText = ScrolledText.ScrolledText(protocolFrame,state='disabled',height=30, width=70)
self.protocolText.grid(column=0, row=0, sticky='NE')
#--------------------------------------------------------------------------------------
self.L = []
#--------------------------------------------------------------------------------------
def enter_data(self):
x = self.labelList[0].cget('text')
y = self.valueList[0].get()
self.L.append(x + ': ' + y)
x = self.labelList[1].cget('text')
y = self.valueList[1].get()
self.L.append(x + ': ' + y)
x = self.labelList[2].cget('text')
y = self.valueList[2].get()
self.L.append(x + ': ' + y)
x = self.labelList[3].cget('text')
y = self.valueList[3].get()
self.L.append(x + ': ' + y)
x = self.eval_state.get()
self.L.append(x)
if self.checkB4 == 1:
y = self.optionBefore.cget('text')
self.L.append(y)
x = self.comment.get('1.0','end')
self.L.append(x)
self.L.append('-------------------------------------\n')
self.protocolText.config(state='normal')
self.protocolText.insert(tk.END, '\n'.join(self.L))
self.protocolText.config(state='disabled')
self.L = []
#------------------------------------------------------------------------------------------
def safe_file(self):
s = self.protocolText.get('1.0','end')
with open('my_json', 'w') as fp:
json.dump(s, fp)
def load_file(self):
options = {}
options['defaultextension'] = '.txt'
options['filetypes'] = [('all files', '.*'), ('text files', '.txt')]
options['initialdir'] = '/home'
options['parent'] = self.parent
options['title'] = "Open a file"
self.protocolText.config(state='normal')
with tkFileDialog.askopenfile(mode='r', **options) as f_handle:
for line in f_handle:
self.protocolText.insert(tk.END, f_handle)
self.protocolText.config(state='disabled')
def AAAlift(self):
self.enterData.lift()
def radonlift(self):
self.radon.lift()
if __name__ == "__main__":
app = testlogger(None)
app.title('Testlogger')
app.mainloop()
When app starts:
When AAA is pressed:
I modified your code slightly. Basically I added containerFrame, to wrap the LabelFrames. I think its easier to make it easer this way. I also added some padding in other places to make the Protocol part inline with others.
#!/usr/bin/python
# -*- coding: utf-8 -*-
import Tkinter as tk
import json
import tkFileDialog
import sys
import ScrolledText
from Tkinter import*
class testlogger(tk.Tk):
def __init__(self,parent):
tk.Tk.__init__(self,parent)
self.parent = parent
self.initialize()
def initialize(self):
self.grid()
#--------------------------------------------------------------------------------------
menubar = tk.Menu(self)
filemenu = tk.Menu(menubar, tearoff=0)
filemenu.add_command(label="New")
filemenu.add_command(label="Open", command=self.load_file)
filemenu.add_command(label="Save", command=self.safe_file)
filemenu.add_command(label="Save as...")
filemenu.add_command(label="Close")
filemenu.add_separator()
filemenu.add_command(label="Exit", command=self.quit)
menubar.add_cascade(label="File", menu=filemenu)
editmenu = tk.Menu(menubar, tearoff=0)
editmenu.add_command(label="Undo")
editmenu.add_separator()
editmenu.add_command(label="Cut")
editmenu.add_command(label="Copy")
editmenu.add_command(label="Paste")
editmenu.add_command(label="Delete")
editmenu.add_command(label="Select All")
menubar.add_cascade(label="Edit", menu=editmenu)
helpmenu = tk.Menu(menubar, tearoff=0)
helpmenu.add_command(label="Help Index")
helpmenu.add_command(label="About...")
menubar.add_cascade(label="Help", menu=helpmenu)
self.config(menu=menubar)
#--------------------------------------------------------------------------------------
treeFrame = tk.Frame(self)
treeFrame.grid(column=0, row=1, sticky='NW')
b1 = Button(treeFrame, text=u'AAA', command=self.AAAlift)
b1.pack(fill='x')
b2 = Button(treeFrame, text=u'RADON', command=self.radonlift)
b2.pack(fill='x')
b3 = Button(treeFrame, text=u'Adaptive Subtract')
b3.pack(fill='x')
b4 = Button(treeFrame, text=u'GMP')
b4.pack(fill='x')
#--------------------------------------------------------------------------------------
#
#
#
#--------------------------------------------------------------------------------------
self.containerFrame = tk.Frame(self)
self.containerFrame.grid(column=1, row=1, columnspan=4, sticky='NW', \
padx=5, pady=5, ipadx=1, ipady=1)
self.enterData = tk.LabelFrame(self.containerFrame, text=" Data Entry ")
#self.enterData.pack(fill=tk.BOTH, expand=1)
self.enterData.grid(column=0, row=0, sticky='NW', ipadx=17)
# self.enterData.grid(column=1, row=1, columnspan=4, sticky='NW', \
# padx=5, pady=5, ipadx=5, ipady=5)
titleAAA = tk.Label(self.enterData, text="AAA")
titleAAA.grid(row=1, columnspan=4, sticky='N', padx=5, pady=2)
self.freqInput = tk.StringVar()
self.freqInput2 = tk.StringVar()
self.thresInput = tk.StringVar()
self.widthInput = tk.StringVar()
self.minFreq = tk.Label(self.enterData, text="Minimum Frequency")
self.minFreq.grid(row=2, column=1, sticky='E', padx=5, pady=2)
minFreqData = tk.Entry(self.enterData, textvariable=self.freqInput)
minFreqData.grid(row=2, column=2, sticky='E', padx=5, pady=2)
self.maxFreq = tk.Label(self.enterData, text="Maximum Frequency")
self.maxFreq.grid(row=3, column=1, sticky='E', padx=5, pady=2)
maxFreqData = tk.Entry(self.enterData, textvariable=self.freqInput2)
maxFreqData.grid(row=3, column=2, sticky='E', padx=5, pady=2)
self.threshold = tk.Label(self.enterData, text="Threshold")
self.threshold.grid(row=2, column=3, sticky='E', padx=5, pady=2)
thresData = tk.Entry(self.enterData, textvariable=self.thresInput)
thresData.grid(row=2, column=4, sticky='E', padx=5, pady=2)
self.width = tk.Label(self.enterData, text="SpatialWidth")
self.width.grid(row=3, column=3, sticky='E', padx=5, pady=2)
widthData = tk.Entry(self.enterData, textvariable=self.widthInput)
widthData.grid(row=3, column=4, sticky='E', padx=5, pady=2)
self.valueList = [self.freqInput, self.freqInput2, self.thresInput, self.widthInput]
self.labelList = [self.minFreq, self.maxFreq, self.threshold, self.width]
enteredAAAData = []
#--------------------------------------------------------------------------------------
self.radon = LabelFrame(self.containerFrame, text=" Data Entry ")
#self.radon.pack(fill=tk.BOTH, expand=1)
self.radon.grid(column=0, row=0, sticky='NW', ipadx=0)
titleRadon = Label(self.radon, text="Radon Fwd Transform")
titleRadon.grid(row=1, columnspan=4, sticky='N', padx=5, pady=2)
self.minMOInput = StringVar()
self.maxMOInput = StringVar()
self.offsetInput = StringVar()
self.numpInput = StringVar()
self.motypeInput = StringVar()
self.maxfreqInput = StringVar()
self.minMO = Label(self.radon, text="Minimum Moveout")
self.minMO.grid(row=2, column=1, sticky='E', padx=5, pady=2)
minMOData = Entry(self.radon, textvariable=self.minMOInput)
minMOData.grid(row=2, column=2, sticky='E', padx=5, pady=2)
self.maxMO = Label(self.radon, text="Maximum Moveout")
self.maxFreq.grid(row=3, column=1, sticky='E', padx=5, pady=2)
maxMOData = Entry(self.radon, textvariable=self.maxMOInput)
maxMOData.grid(row=3, column=2, sticky='E', padx=5, pady=2)
self.offset = Label(self.radon, text="Reference Offset")
self.offset.grid(row=2, column=3, sticky='E', padx=5, pady=2)
offsetData = Entry(self.radon, textvariable=self.offsetInput)
offsetData.grid(row=2, column=4, sticky='E', padx=5, pady=2)
self.numP = Label(self.radon, text="Number of P-Traces")
self.numP.grid(row=3, column=3, sticky='E', padx=5, pady=2)
numPData = Entry(self.radon, textvariable=self.numpInput)
numPData.grid(row=3, column=4, sticky='E', padx=5, pady=2)
self.motype = Label(self.radon, text="Moveout Type")
self.motype.grid(row=4, column=1, sticky='E', padx=5, pady=2)
motypeData = Entry(self.radon, textvariable=self.motypeInput)
motypeData.grid(row=4, column=2, sticky='E', padx=5, pady=2)
self.maxfreq = Label(self.radon, text="Maximum Frequency")
self.maxfreq.grid(row=4, column=3, sticky='E', padx=5, pady=2)
maxfreqData = Entry(self.radon, textvariable=self.maxfreqInput)
maxfreqData.grid(row=4, column=4, sticky='E', padx=5, pady=2)
self.valueList = [self.minMOInput, self.maxMOInput, self.offsetInput, self.numpInput, self.motypeInput, self.maxfreqInput]
self.labelList = [self.minMO, self.maxMO, self.offset, self.numP, self.motype, self.maxfreq]
enteredRadonData = []
#--------------------------------------------------------------------------------------
evalData = tk.Frame(self)
evalData.grid(column=1, row=2, sticky='NW', \
padx=5, pady=5, ipadx=5, ipady=5)
evalLabel = tk.Label(evalData, text="Evaluation")
evalLabel.grid(row=1, column=1, columnspan=3, sticky='N', padx=5, pady=2)
self.eval_state = tk.StringVar()
goodRadio = tk.Radiobutton(evalData, text="Good", variable=self.eval_state, value='Good')
goodRadio.grid(row=2, column=1, sticky='W', padx=5, pady=2)
badRadio = tk.Radiobutton(evalData, text="Bad", variable=self.eval_state, value='Bad')
badRadio.grid(row=2, column=2, sticky='W', padx=5, pady=2)
sameRadio = tk.Radiobutton(evalData, text="Same", variable=self.eval_state, value='Same')
sameRadio.grid(row=2, column=3, sticky='W', padx=5, pady=2)
qcDisp = tk.Label(evalData, text="QC Displays:")
qcDisp.grid(row=2,column=4, sticky='W', padx=10, pady=2)
self.checkB4 = tk.IntVar()
optionBefore = tk.Checkbutton(evalData, text="Before", variable=self.checkB4, onvalue=1, offvalue=0)
optionBefore.grid(row=1, column=5, sticky='W', padx=5, pady=2)
optionAfter = tk.Checkbutton(evalData, text="After", onvalue=1, offvalue=0)
optionAfter.grid(row=2, column=5, sticky='W', padx=5, pady=2)
optionDiff = tk.Checkbutton(evalData, text="Difference", onvalue=1, offvalue=0)
optionDiff.grid(row=3, column=5, sticky='W', padx=5, pady=2)
optionSpectrum = tk.Checkbutton(evalData, text="Frequency Spectrum", onvalue=1, offvalue=0)
optionSpectrum.grid(row=1, column=6, sticky='W', padx=5, pady=2)
optionAuto = tk.Checkbutton(evalData, text="Auto Correlation", onvalue=1, offvalue=0)
optionAuto.grid(row=2, column=6, sticky='W', padx=5, pady=2)
optionBanana = tk.Checkbutton(evalData, text="I'm a Banana", onvalue=1, offvalue=0)
optionBanana.grid(row=3, column=6, sticky='W', padx=5, pady=2)
#--------------------------------------------------------------------------------------
self.comment = tk.Text(self, height=5, bg='white')
self.comment.grid(column=1, row=3, sticky='NW', \
padx=5, pady=5, ipadx=5, ipady=5)
submit_b = tk.Button(self, text=u"Submit", command=self.enter_data)
submit_b.grid(column=1, row=4, sticky='NE')
#--------------------------------------------------------------------------------------
protocolFrame = tk.LabelFrame(self, text="Protocol")
protocolFrame.grid(row=1, column=2, padx=45, pady=5, rowspan=3, sticky='NW')
self.protocolText = ScrolledText.ScrolledText(protocolFrame,state='disabled',height=30, width=70)
self.protocolText.grid(column=0, row=0, sticky='NE')
#--------------------------------------------------------------------------------------
self.L = []
#--------------------------------------------------------------------------------------
def enter_data(self):
x = self.labelList[0].cget('text')
y = self.valueList[0].get()
self.L.append(x + ': ' + y)
x = self.labelList[1].cget('text')
y = self.valueList[1].get()
self.L.append(x + ': ' + y)
x = self.labelList[2].cget('text')
y = self.valueList[2].get()
self.L.append(x + ': ' + y)
x = self.labelList[3].cget('text')
y = self.valueList[3].get()
self.L.append(x + ': ' + y)
x = self.eval_state.get()
self.L.append(x)
if self.checkB4 == 1:
y = self.optionBefore.cget('text')
self.L.append(y)
x = self.comment.get('1.0','end')
self.L.append(x)
self.L.append('-------------------------------------\n')
self.protocolText.config(state='normal')
self.protocolText.insert(tk.END, '\n'.join(self.L))
self.protocolText.config(state='disabled')
self.L = []
#------------------------------------------------------------------------------------------
def safe_file(self):
s = self.protocolText.get('1.0','end')
with open('my_json', 'w') as fp:
json.dump(s, fp)
def load_file(self):
options = {}
options['defaultextension'] = '.txt'
options['filetypes'] = [('all files', '.*'), ('text files', '.txt')]
options['initialdir'] = '/home'
options['parent'] = self.parent
options['title'] = "Open a file"
self.protocolText.config(state='normal')
with tkFileDialog.askopenfile(mode='r', **options) as f_handle:
for line in f_handle:
self.protocolText.insert(tk.END, f_handle)
self.protocolText.config(state='disabled')
def AAAlift(self):
#self.enterData.grid_forget()
self.radon.grid_remove()
self.enterData.grid()
def radonlift(self):
self.enterData.grid_remove()
self.radon.grid()
if __name__ == "__main__":
app = testlogger(None)
app.title('Testlogger')
app.mainloop()
The screenshots are:
Obviously more work is needed to make everything "even" and inline with each other, but pressing AAA and RADON buttons works as expected (I think). You can expand/amend on my modifications, and hopefully it will allow you to achieve desired effect.
Related
Currently I have one window that displays two Treeview frames(festo and transformer) that of identical layout. These treeview layout should display different user data from txt files. Hence, the no of Treeview windows are dynamic based on the no txt files in a folder. Is it possible to create/generate multiple pop-up Treeview windows of the same layout upon a button click?
class HomePage(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
self.notebook = ttk.Notebook() # Create a notebook widget
self.add_tab1()
#self.add_tab2()
self.notebook.grid(row=0)
self.notebook.pack(expand=1, fill="both")
def add_tab1(self):
tab1 = tab_one(self.notebook)
self.notebook.add(tab1, text="Home")
def add_tab2(self):
tab2 = ttk.Notebook()
self.notebook.add(tab2, text="Reports")
class data_table(object):
def __init__(self, site, panels_count, tev_count):
self.site = site
self.panels_count = panels_count
self.tev_count = tev_count
class tab_one(Frame):
def __init__(self, *args, **kwargs):
Frame.__init__(self, *args, **kwargs)
# Creating frames on the window/canvas for the first tab
frame_selectfile = tk.LabelFrame(self, text="Step 1: Zip File Extraction ", bd=6) # Frame1 on the window/canvas
frame_selectfile.grid(column=0, row=0, padx=10, pady=10, sticky='NSEW') # Positioning frame1
frame_selectfile.configure(borderwidth=1)
self.grid_columnconfigure(0, weight=1) # Configuring the column for the main window/canvas
self.grid_rowconfigure(0, weight=1) # Configuring the row for the main window/canvas
frame_checkpd = tk.LabelFrame(self, text="Step 2: Check PD ", bd=6) # Frame2 on the window/canvas
frame_checkpd.grid(column=1, row=0, padx=10, pady=10, sticky='NSEW') # Positioning frame2
frame_checkpd.configure(borderwidth=1)
self.grid_columnconfigure(1, weight=1) # Configuring the column for the main window/canvas
self.grid_rowconfigure(1, weight=1) # Configuring the row for the main window/canvas
frame_festo = tk.LabelFrame(self, text="Festo: ", bd=6) # Frame1 on the window/canvas
frame_festo.grid(column=0, row=1, padx=10, pady=10, sticky='NSEW') # Positioning frame1
frame_festo.configure(borderwidth=1)
self.grid_columnconfigure(1, weight=1) # Configuring the column for the main window/canvas
self.grid_rowconfigure(1, weight=1) # Configuring the row for the main window/canvas
frame_transform = tk.LabelFrame(self, text="Transformer: ", bd=6) # Frame1 on the window/canvas
frame_transform.grid(column=1, row=1, padx=10, pady=10, sticky='NSEW') # Positioning frame1
frame_transform.configure(borderwidth=1)
self.grid_columnconfigure(1, weight=1) # Configuring the column for the main window/canvas
self.grid_rowconfigure(1, weight=1) # Configuring the row for the main window/canvas
# Initializing all variables in frame_selectfile
file_ID = tk.StringVar()
file_ID2 = tk.StringVar()
location_id = tk.StringVar()
location_id2 = tk.StringVar()
unzip_status = tk.StringVar()
tmpdir = tempfile.TemporaryDirectory().name
#self.create_dir_ifnot_exist(tmpdir)
zip_filename = tk.StringVar()
site_id = tk.StringVar()
site_id.set("0")
data_table_list = []
file_counter = tk.StringVar()
# Initializing all variables in frame_festo
festo_date_id = tk.StringVar()
festo_job_id = tk.StringVar()
festo_engineer_id = tk.StringVar()
festo_station_id = tk.StringVar()
festo_voltage_id = tk.StringVar()
festo_db_id = tk.StringVar()
festo_pd_id = tk.StringVar()
# Initializing all variables in frame_transform
transform_date_id = tk.StringVar()
transform_job_id = tk.StringVar()
transform_engineer_id = tk.StringVar()
transform_station_id = tk.StringVar()
transform_voltage_id = tk.StringVar()
transform_db_id = tk.StringVar()
transform_pd_id = tk.StringVar()
topframe = tk.LabelFrame(frame_festo, bd=0)
topframe_transform = tk.LabelFrame(frame_transform, bd=0)
middleframe = tk.LabelFrame(frame_selectfile, bd=5)
databaseView = ttk.Treeview(middleframe, selectmode="browse")
#label_filename = tk.Label(frame_selectfile, text=" ", width=10, relief='flat').grid(column=0, row=1, padx=5, pady=5, sticky='NW')
label_filelocation = tk.Label(frame_selectfile, text="File Location:", width=12, relief='flat').grid(column=0, row=0, padx=5, pady=5, sticky='NW')
filename_Entry = tk.Label(frame_selectfile, width=52, textvariable=file_ID)
filename_Entry.grid(column=1, row=0, padx=5, pady=5, sticky='NW')
filename_Entry.configure(state='normal')
filelocation_Entry = tk.Entry(frame_selectfile, width=60, textvariable=location_id)
filelocation_Entry.grid(column=1, row=0, padx=5, pady=5, sticky='W')
filelocation_Entry.configure(background='palegreen', foreground='black')
middleframe2 = tk.LabelFrame(frame_festo, bd=5)
databaseView2 = ttk.Treeview(middleframe2, selectmode="browse")
transform_middle_frame = tk.LabelFrame(frame_transform, bd=5)
transformView = ttk.Treeview(transform_middle_frame, selectmode="browse")
#label_filename2 = tk.Label(topframe, text=" ", width=10, relief='flat').grid(column=0, row=1, padx=5, pady=5, sticky='NW')
#label_filelocation2 = tk.Label(topframe, text="File Location:", width=12, relief='flat').grid(column=0, row=2, padx=5, pady=5, sticky='NW')
label_festo_date_id = tk.Label(topframe, text="Scanned Date:", width=12, relief='flat').grid(column=0, row=0, padx=5, pady=5, sticky='NW')
label_festo_job_id = tk.Label(topframe, text="Job No:", width=12, relief='flat').grid(column=2, row=0, padx=5, pady=5, sticky='NW')
label_festo_engineer_id = tk.Label(topframe, text="Engineer:", width=12, relief='flat').grid(column=4, row=0, padx=5, pady=5, sticky='NW')
label_festo_station_id = tk.Label(topframe, text="Station:", width=12, relief='flat').grid(column=0, row=1, padx=5, pady=5, sticky='W')
label_festo_voltage_id = tk.Label(topframe, text="Operating Voltage(kV):", width=18, relief='flat').grid(column=2, row=1, padx=5, pady=5, sticky='NW')
label_festo_db_id = tk.Label(topframe, text="Max dB:", width=12, relief='flat').grid(column=4, row=1, padx=5, pady=5, sticky='NW')
#label_festo_pd_id = tk.Label(topframe, text="Max PD:", width=12, relief='flat').grid(column=0, row=2, padx=5, pady=5, sticky='NW')
festo_date_id_Entry = tk.Entry(topframe, width=15, textvariable=festo_date_id)
festo_date_id_Entry.grid(column=1, row=0, padx=5, pady=5, sticky='NW')
festo_date_id_Entry.configure(state='normal')
festo_job_id_Entry = tk.Entry(topframe, width=15, textvariable=festo_job_id)
festo_job_id_Entry.grid(column=3, row=0, padx=5, pady=5, sticky='NW')
festo_job_id_Entry.configure(state='normal')
festo_engineer_id_Entry = tk.Entry(topframe, width=15, textvariable=festo_engineer_id)
festo_engineer_id_Entry.grid(column=5, row=0, padx=5, pady=5, sticky='NW')
festo_engineer_id_Entry.configure(state='normal')
festo_station_id_Entry = tk.Entry(topframe, width=15, textvariable=festo_station_id)
festo_station_id_Entry.grid(column=1, row=1, padx=5, pady=5, sticky='NW')
festo_station_id_Entry.configure(state='normal')
festo_voltage_id_Entry = tk.Entry(topframe, width=15, textvariable=festo_voltage_id)
festo_voltage_id_Entry.grid(column=3, row=1, padx=5, pady=5, sticky='NW')
festo_voltage_id_Entry.configure(state='normal')
festo_db_id_Entry = tk.Entry(topframe, width=15, textvariable=festo_db_id)
festo_db_id_Entry.grid(column=5, row=1, padx=5, pady=5, sticky='NW')
festo_db_id_Entry.configure(state='normal')
label_transform_date_id = tk.Label(topframe_transform, text="Scanned Date:", width=12, relief='flat').grid(column=0, row=0, padx=5, pady=5, sticky='NW')
label_transform_job_id = tk.Label(topframe_transform, text="Job No:", width=12, relief='flat').grid(column=2, row=0, padx=5, pady=5, sticky='NW')
label_transform_engineer_id = tk.Label(topframe_transform, text="Engineer:", width=12, relief='flat').grid(column=4, row=0, padx=5, pady=5, sticky='NW')
label_transform_station_id = tk.Label(topframe_transform, text="Station:", width=12, relief='flat').grid(column=0, row=1, padx=5, pady=5, sticky='NW')
label_transform_voltage_id = tk.Label(topframe_transform, text="Operating Voltage(kV):", width=18, relief='flat').grid(column=2, row=1, padx=5, pady=5, sticky='NW')
label_transform_db_id = tk.Label(topframe_transform, text="Max dB:", width=12, relief='flat').grid(column=4, row=1, padx=5, pady=5, sticky='NW')
#label_transform_pd_id = tk.Label(topframe, text="Max PD:", width=12, relief='flat').grid(column=0, row=2, padx=5, pady=5, sticky='NW')
transform_date_id_Entry = tk.Entry(topframe_transform, width=15, textvariable=transform_date_id)
transform_date_id_Entry.grid(column=1, row=0, padx=5, pady=5, sticky='NW')
transform_date_id_Entry.configure(state='normal')
transform_job_id_Entry = tk.Entry(topframe_transform, width=15, textvariable=transform_job_id)
transform_job_id_Entry.grid(column=3, row=0, padx=5, pady=5, sticky='NW')
transform_job_id_Entry.configure(state='normal')
transform_engineer_id_Entry = tk.Entry(topframe_transform, width=15, textvariable=transform_engineer_id)
transform_engineer_id_Entry.grid(column=5, row=0, padx=5, pady=5, sticky='NW')
transform_engineer_id_Entry.configure(state='normal')
transform_station_id_Entry = tk.Entry(topframe_transform, width=15, textvariable=transform_station_id)
transform_station_id_Entry.grid(column=1, row=1, padx=5, pady=5, sticky='NW')
transform_station_id_Entry.configure(state='normal')
transform_voltage_id_Entry = tk.Entry(topframe_transform, width=15, textvariable=transform_voltage_id)
transform_voltage_id_Entry.grid(column=3, row=1, padx=5, pady=5, sticky='NW')
transform_voltage_id_Entry.configure(state='normal')
transform_db_id_Entry = tk.Entry(topframe_transform, width=15, textvariable=transform_db_id)
transform_db_id_Entry.grid(column=5, row=1, padx=5, pady=5, sticky='NW')
transform_db_id_Entry.configure(state='normal')
unzip_status.set("")
label_unzipstatus = tk.Label(frame_selectfile, width=20, relief='flat', textvariable=unzip_status)
label_unzipstatus.grid(column=1, row=5, padx=5, pady=5, sticky='NSEW')
selectzip_button = tk.Button(frame_selectfile, width=20, text="Select Zip File", command=lambda: self.upload_action(location_id, zip_filename, tmpdir))
selectzip_button.grid(column=1, row=3, padx=5, pady=3, ipady=3, sticky='SW')
unzip_button = tk.Button(frame_selectfile, width=20, text="Extract", command=lambda: self.extract_nested_zip(databaseView, data_table_list, location_id.get(), tmpdir, zip_filename, site_id, False))
unzip_button.grid(column=1, row=3, padx=5, pady=3, ipady=3, sticky='NE')
# Creating LabelFrame in frame_unzip
upperframe = tk.LabelFrame(frame_selectfile, bd=0)
frame_selectfile.rowconfigure(0, weight=1)
frame_selectfile.columnconfigure(2, weight=1)
upperframe.grid(column=0, row=6, columnspan=2, sticky='W')
# middleframe = tk.LabelFrame(frame_selectfile, bd=5)
middleframe.configure(borderwidth=1)
frame_selectfile.columnconfigure(2, weight=1)
frame_selectfile.rowconfigure(1, weight=1)
middleframe.grid(column=0, row=7, columnspan=2, sticky="NSEW")
middleframe2.configure(borderwidth=1)
frame_festo.columnconfigure(2, weight=1)
frame_festo.rowconfigure(1, weight=1)
middleframe2.grid(column=0, row=1, columnspan=2, sticky="NSEW")
transform_middle_frame.configure(borderwidth=1)
frame_transform.columnconfigure(2, weight=1)
frame_transform.rowconfigure(1, weight=1)
transform_middle_frame.grid(column=0, row=1, columnspan=2, sticky="NSEW")
# lowerframe = tk.LabelFrame(frame_selectfile, bd=0)
# lowerframe.grid(column=0, row=7)
# frame_selectfile.columnconfigure(2, weight=1)
# frame_selectfile.rowconfigure(2, weight=0)
topframe.configure(borderwidth=1)
frame_festo.columnconfigure(2, weight=1)
frame_festo.rowconfigure(1, weight=1)
topframe.grid(column=0, row=0, columnspan=2, sticky="NSEW")
topframe_transform.configure(borderwidth=1)
frame_transform.columnconfigure(2, weight=1)
frame_transform.rowconfigure(1, weight=1)
topframe_transform.grid(column=0, row=0, columnspan=2, sticky="NSEW")
# Labels in frame_unzip
label18 = tk.Label(upperframe, text="Number of sites:", relief='flat')
label18.grid(column=0, row=0, padx=5, pady=5, sticky='W')
site_Entry = tk.Entry(upperframe, width=45, textvariable=site_id)
site_Entry.grid(column=1, row=0, padx=10, pady=5, sticky='E')
site_Entry.configure(state='normal', background='palegreen', foreground='black')
# Button Widgets in frame_unzip
#unzip_btn = tk.Button(upperframe, width=10, text="Unzip File", command=lambda: Unzip(databaseview))
#unzip_btn.grid(column=2, row=0, padx=0, pady=5, ipady=2, sticky='E')
# label_details = tk.Label(upperframe, text=" ", relief='flat')
# label_details.grid(column=0, row=2, padx=5, pady=0, sticky='W')
# Combobox Widgets in frame_unzip
# initializing treeview in frame_unzip
# databaseView = ttk.Treeview(middleframe, selectmode="browse")
databaseView.columnconfigure(2, weight=1)
databaseView.grid(column=0, row=0, columnspan=2, sticky="NSEW")
databaseView2.columnconfigure(2, weight=1)
databaseView2.grid(column=0, row=0, columnspan=2, sticky="NSEW")
transformView.columnconfigure(2, weight=1)
transformView.grid(column=0, row=0, columnspan=2, sticky="NSEW")
# Creating treeview in frame_unzip
vsb = Scrollbar(middleframe, orient="vertical", command=databaseView.yview())
hsb = Scrollbar(middleframe, orient="horizontal")
vsb = Scrollbar(middleframe2, orient="vertical", command=databaseView2.yview())
hsb = Scrollbar(middleframe2, orient="horizontal")
vsb = Scrollbar(transform_middle_frame, orient="vertical", command=transformView.yview())
hsb = Scrollbar(transform_middle_frame, orient="horizontal")
middleframe.columnconfigure(0, weight=1)
middleframe.rowconfigure(0, weight=1)
databaseView["show"] = "headings"
databaseView["columns"] = ("site", "panels", "tevs")
vsb.configure(command=databaseView.yview)
# hsb.configure(command=databaseView.xview)
vsb.grid(column=1, row=0, sticky="NS")
# hsb.grid(column=0, row=1, sticky="WE")
middleframe2.columnconfigure(0, weight=1)
middleframe2.rowconfigure(0, weight=1)
databaseView2["show"] = "headings"
databaseView2["columns"] = ("num", "name", "component", "location", "phase", "db", "prpd", "pulse", "pd")
vsb.configure(command=databaseView2.yview)
# hsb.configure(command=databaseView.xview)
vsb.grid(column=1, row=0, sticky="NS")
transform_middle_frame.columnconfigure(0, weight=1)
transform_middle_frame.rowconfigure(0, weight=1)
transformView["show"] = "headings"
transformView["columns"] = ("num", "name", "component", "location", "phase", "db", "prpd", "pulse", "pd")
vsb.configure(command=transformView.yview)
# hsb.configure(command=databaseView.xview)
vsb.grid(column=1, row=0, sticky="NS")
# Treeview column headings
databaseView.heading("site", text="Site")
databaseView.column("site", anchor='w', width=250)
databaseView.heading("panels", text="Number of Panels")
databaseView.column("panels", anchor='center', width=100)
databaseView.heading("tevs", text="Number of TEVs")
databaseView.column("tevs", anchor='center', width=100)
# Treeview column headings festo
databaseView2.heading("num", text="Panel")
databaseView2.column("num", anchor='w', width=100)
databaseView2.heading("name", text="Tev")
databaseView2.column("name", anchor='center', width=150)
databaseView2.heading("component", text="Component")
databaseView2.column("component", anchor='center', width=150)
databaseView2.heading("location", text="Sublocation")
databaseView2.column("location", anchor='w', width=100)
databaseView2.heading("phase", text="Phase Ref Lock")
databaseView2.column("phase", anchor='center', width=100)
databaseView2.heading("db", text="dB")
databaseView2.column("db", anchor='center', width=100)
databaseView2.heading("prpd", text="PRPD")
databaseView2.column("prpd", anchor='w', width=100)
databaseView2.heading("pulse", text="Pulse Wave")
databaseView2.column("pulse", anchor='center', width=100)
databaseView2.heading("pd", text="PD%")
databaseView2.column("pd", anchor='center', width=100)
# Treeview column headings transform
transformView.heading("num", text="Panel")
transformView.column("num", anchor='w', width=100)
transformView.heading("name", text="Tev")
transformView.column("name", anchor='center', width=150)
transformView.heading("component", text="Component")
transformView.column("component", anchor='center', width=150)
transformView.heading("location", text="Sublocation")
transformView.column("location", anchor='w', width=100)
transformView.heading("phase", text="Phase Ref Lock")
transformView.column("phase", anchor='center', width=100)
transformView.heading("db", text="dB")
transformView.column("db", anchor='center', width=100)
transformView.heading("prpd", text="PRPD")
transformView.column("prpd", anchor='w', width=100)
transformView.heading("pulse", text="Pulse Wave")
transformView.column("pulse", anchor='center', width=100)
transformView.heading("pd", text="PD%")
transformView.column("pd", anchor='center', width=100)
# Widgets in Frame 3
#label_checkstatus = tk.Label(frame_checkpd, text="Status", width=5, relief='flat').grid(column=2, row=0, padx=5, pady=5, sticky='E')
#label_checkstatuscolour = tk.Label(frame_checkpd, text=" ", bg="limegreen", width=5, relief='flat').grid(column=2, row=1, padx=5, pady=5, sticky='E')
findpd_btn = tk.Button(frame_checkpd, width=20, text="Find PDs", command=lambda: self.run_pd_model_exe(tmpdir, zip_filename))
findpd_btn.grid(column=1, row=1, padx=5, pady=5, sticky='E')
export_pdf_btn = tk.Button(frame_checkpd, width=20, text="Export to PDF",
command=lambda: self.export_to_pdf(tmpdir, zip_filename))
export_pdf_btn.grid(column=2, row=1, padx=5, pady=5, sticky='E')
file_counter = 0
find_files_btn = tk.Button(frame_checkpd, width=20, text="Check Files", command=lambda: self.check_files(file_counter, find_files_btn))
find_files_btn.grid(column=3, row=1, padx=5, pady=5, sticky='NSEW')
print(file_counter)
file_counter = 0
#selectzip_button.grid(column=1, row=3, padx=5, pady=3, ipady=3, sticky='SW')
def check_files(self, counter, btn):
# folder path
dir_path = r'C:\Users\Documents\GUI\input_folder'
count = 0
# Iterate directory
for path in os.listdir(dir_path):
# check if current path is a file
if os.path.isfile(os.path.join(dir_path, path)):
count += 1
print('File count:', count)
return count
This is my code:
mycanvas = Canvas(self.search_result_frame)
mycanvas.pack(side=LEFT)
yscrollbar = ttk.Scrollbar(self.search_result_frame, orient="vertical", command=mycanvas.yview)
yscrollbar.pack(side=RIGHT, fill=Y)
mycanvas.configure(yscrollcommand=yscrollbar.set)
mycanvas.bind('<Configure>', lambda e: mycanvas.configure(scrollregion = mycanvas.bbox('all')))
self.sample_frame = Frame(mycanvas)
mycanvas.create_window((0,0), window=self.sample_frame, anchor=E)
for widget in self.search_result_frame.winfo_children():
widget.destroy()
if len(matching_bills) > 0:
for bill in matching_bills:
with open(f'{self.bill_folder}//{bill}//data//bill_details.json', 'r') as bill_json_file:
bill_details = json.loads(bill_json_file.read())
customer_name = bill_details["customer_details"][0]
payment_method = bill_details["payment_method"]
date_of_issue = bill_details["date_of_issue"]
date_of_issue = datetime.strptime(date_of_issue, "%d/%m/%Y")
date_of_issue = date_of_issue.strftime("%d %b %Y")
# # -------------------- Search Result Frame Contents
result_frame = Frame(self.sample_frame, bg=self.bg3, bd=5, relief=GROOVE)
result_frame.pack(fill=BOTH, pady=2)
result_billno_lbl = Label(result_frame, text=bill, bg=self.bg1, fg="#FFF", font=self.search_results_font1, padx=22, pady=3)
result_billno_lbl.grid(row=0, column=0, padx=50, pady=8, sticky=W)
billed_to_lbl = Label(result_frame, text=f"Billed To - {customer_name}", bg=self.bg1, fg="#FFF", font=self.search_results_font2, bd=2, relief=RAISED, padx=12, pady=3)
billed_to_lbl.grid(row=0, column=1, padx=80, sticky=W)
billed_type_lbl = Label(result_frame, text=f"Bill Type - {payment_method}", bg=self.bg1, fg="#FFF", font=self.search_results_font2, bd=2, relief=RAISED, padx=12, pady=3)
billed_type_lbl.grid(row=0, column=2, sticky=W)
issued_on_lbl = Label(result_frame, text=f"Issued On - {date_of_issue}", bg=self.bg1, fg="#FFF",
font=self.search_results_font2, bd=2, relief=RAISED, padx=12, pady=3)
issued_on_lbl.grid(row=0, column=3, padx=80, sticky=W)
view_btn = Button(result_frame, text="View", font="Comicsan 14", bd=2, relief=GROOVE, bg="#000", fg="#FFF", padx=1, command=lambda bill=bill: self.view_bill(bill))
view_btn.grid(row=0, column=4, padx=3, columnspan=2, sticky=W)
elif len(matching_bills) == 0:
for widgets in self.search_result_frame.winfo_children():
widgets.destroy()
no_result_lbl = Label(self.search_result_frame, text=f"No search result found for {bill_cat}", font=self.search_results_font1, bg=self.bg3, fg="#FFF")
no_result_lbl.pack(fill=X)
When I run it, it shows me the bad window path name ".!labelframe.!canvas.!frame error and when I try to do the same thing without object-oriented in tkinter then it works well !
I am mainly coding on my MAC.
I created a GUI that is used for a tool I am using to automate things with selenium.
I have used .grid for all widgets in my GUI.
But when I open the GUI on my Windows laptop at home (same resolution but much smaller monitor panel) it is totally messed up.
Here are two screenshot showing the problem,
Messed up layout on Win Laptop (17,3")
The second screenshot shows how it should look.
This is the code I used for the grid layout:
# General GUI settings
app = Tk()
app.title('trade_buddy')
app.geometry('605x800')
app.minsize(605, 800)
app.maxsize(605, 800)
app.grid_rowconfigure(0, weight=1)
app.grid_rowconfigure(1, weight=1)
app.grid_rowconfigure(2, weight=1)
app.grid_rowconfigure(3, weight=1)
app.grid_rowconfigure(4, weight=1)
app.grid_rowconfigure(5, weight=1)
app.grid_rowconfigure(6, weight=1)
app.grid_rowconfigure(7, weight=1)
app.grid_rowconfigure(8, weight=1)
app.grid_rowconfigure(9, weight=1)
app.grid_rowconfigure(10, weight=1)
app.grid_rowconfigure(11, weight=1)
app.grid_rowconfigure(12, weight=1)
app.grid_rowconfigure(13, weight=1)
#Background label
image = Image.open('v2.0/lolo.png')
image = image.resize((600,450), Image.ANTIALIAS)
copy_of_image = image.copy()
photo = ImageTk.PhotoImage(image)
label = tk.Label(app, image = photo)
label.place(x=0, y=0)
#Buttons
b_init = tk.Button(app,text='Initialize',font='Tahoma 10 bold',bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d',padx=8, pady=10, command=lambda:threading.Thread(target=tb,daemon=True).start())
b_exit = tk.Button(app,text='Exit',font='Tahoma 10 bold',padx=8,bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d', pady=10,command=lambda:threading.Thread(target=exit_tb,daemon=True).start())
b_start = tk.Button(app,text='Start',font='Tahoma 10 bold',bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d',padx=8, pady=10,command=lambda:threading.Thread(target=filters,daemon=True).start())
b_pause = tk.Button(app,text='Pause',font='Tahoma 10 bold',bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d',padx=8, pady=10,command=lambda:threading.Thread(target=stop_tb,daemon=True).start())
b_tfm = tk.Button(app,text='TFM',font='Tahoma 10 bold',bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d',padx=8, pady=10,command=lambda:threading.Thread(target=tfm,daemon=True).start())
#Labels
l_maxBO = tk.Label(app,text='Maximum buy price:',bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10')
l_itemsontf = tk.Label(text='# of items on transfer list:',bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10')
l_speed = tk.Label(text='Choose speed:',bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10 bold')
l_routine = tk.Label(text='Choose routine:',bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10 bold')
#Entries
e_maxBO = tk.Entry(app, width=10, bg='#1e1e1f', fg='#f8f09d', font='Tahoma 10')
e_itemsontf = tk.Entry(app, width=10, bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10')
e_fixedsellprice = tk.Entry(app, width=10, bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10')
#Text box
t_outputbox = tk.Text(app, width=99, height=27, font='Tahoma 10',bg='#2c2c2c', fg='#f8f09d', relief=SUNKEN, highlightthickness="1")
#Grid Layout
l_maxBO.grid(row=0, column=0, sticky='w', padx=5, pady=5)
l_itemsontf.grid(row=1, column=0, sticky='w', padx=5, pady=5)
l_speed.grid(row=3, column=0, sticky='w', padx=5, pady=1, ipady=1)
l_routine.grid(row=7, column=0, sticky='w', padx=5, pady=1, ipady=1)
e_maxBO.grid(row=0, column=1, sticky='w', padx=5, pady=5)
e_itemsontf.grid(row=1, column=1, sticky='w', padx=5, pady=5)
e_fixedsellprice.grid(row=11, column=0, sticky='w', padx=5, pady=3)
b_exit.grid(row=12, column=8, sticky='sw', padx=5, pady=10)
b_init.grid(row=12, column=4, sticky='sw', padx=5, pady=10)
b_start.grid(row=12, column=0, sticky='sw', padx=5, pady=10)
b_pause.grid(row=12, column=1, sticky='sw', padx=5, pady=10)
b_tfm.grid(row=12, column=2, sticky='sw', padx=5, pady=10)
r_normal.grid(row=4, column=0, sticky='w', padx=5, pady=1)
r_fast.grid(row=5, column=0, sticky='w', padx=5, pady=1)
r_slow.grid(row=6, column=0, sticky='w', padx=5, pady=1)
r_buyonly.grid(row=8, column=0, sticky='w', padx=5, pady=1)
r_fullroutine.grid(row=9, column=0, sticky='w', padx=5, pady=1)
r_buysellfixed.grid(row=10, column=0, sticky='w', padx=5, pady=1)
t_outputbox.grid(row=13, column=0, columnspan=13, rowspan=13, sticky='nsew', padx=5, pady=10)
As a coding beginner, I really have no idea what else I could change.
I already changed from .place to .grid but the problem is still the same.
Does anyone have an idea how I could setup my GUI that it keeps the minimum required geometry relations no matter on what monitor I work?
Here is an example of forcing it to look like the second picture.
import tkinter as tk
from PIL import ImageTk, Image
# General GUI settings
app = tk.Tk()
app.configure(bg="black")
#Background label
image = Image.open('test.png')
image = image.resize((200,200), Image.ANTIALIAS)
copy_of_image = image.copy()
photo = ImageTk.PhotoImage(image)
label = tk.Label(app, image = photo)
label.grid(row=3, column=1, sticky='w')
#others
r_normal = tk.Radiobutton(app, text="Normal Speed")
r_fast = tk.Radiobutton(app, text="Fast Speed")
r_slow = tk.Radiobutton(app, text="Slow Speed")
r_buyonly = tk.Radiobutton(app, text="Buy only")
r_fullroutine = tk.Radiobutton(app, text="Full routine (optimized price)")
r_buysellfixed = tk.Radiobutton(app, text="Buy and sell for fixed price")
#Buttons
b_init = tk.Button(app,text='Initialize',font='Tahoma 10 bold',bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d',padx=8, pady=10, command=lambda:threading.Thread(target=tb,daemon=True).start())
b_exit = tk.Button(app,text='Exit',font='Tahoma 10 bold',padx=8,bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d', pady=10,command=lambda:threading.Thread(target=exit_tb,daemon=True).start())
b_start = tk.Button(app,text='Start',font='Tahoma 10 bold',bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d',padx=8, pady=10,command=lambda:threading.Thread(target=filters,daemon=True).start())
b_pause = tk.Button(app,text='Pause',font='Tahoma 10 bold',bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d',padx=8, pady=10,command=lambda:threading.Thread(target=stop_tb,daemon=True).start())
b_tfm = tk.Button(app,text='TFM',font='Tahoma 10 bold',bg='#f8f09d',fg='#1e1e1f',activebackground='#1e1e1f',activeforeground='#f8f09d',padx=8, pady=10,command=lambda:threading.Thread(target=tfm,daemon=True).start())
#Labels
l_maxBO = tk.Label(app,text='Maximum buy price:',bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10')
l_itemsontf = tk.Label(text='# of items on transfer list:',bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10')
l_speed = tk.Label(text='Choose speed:',bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10 bold')
l_routine = tk.Label(text='Choose routine:',bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10 bold')
#Entries
e_maxBO = tk.Entry(app, width=10, bg='#1e1e1f', fg='#f8f09d', font='Tahoma 10')
e_itemsontf = tk.Entry(app, width=10, bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10')
e_fixedsellprice = tk.Entry(app, width=10, bg='#1e1e1f', fg='#f8f09d',font='Tahoma 10')
#Text box
t_outputbox = tk.Text(app, width=99, height=27, font='Tahoma 10',bg='#2c2c2c', fg='#f8f09d', relief=tk.SUNKEN, highlightthickness="1")
#Grid Layout
l_maxBO.grid(row=0, column=0, sticky='w', padx=5, pady=5)
l_itemsontf.grid(row=1, column=0, sticky='w', padx=5, pady=5)
l_speed.grid(row=3, column=0, sticky='w', padx=5, pady=1, ipady=1)
l_routine.grid(row=7, column=0, sticky='w', padx=5, pady=1, ipady=1)
e_maxBO.grid(row=0, column=1, sticky='w', padx=5, pady=5)
e_itemsontf.grid(row=1, column=1, sticky='w', padx=5, pady=5)
e_fixedsellprice.grid(row=11, column=0, sticky='w', padx=5, pady=3)
b_exit.grid(row=12, column=8, sticky='sw', padx=5, pady=10)
b_init.grid(row=12, column=4, sticky='sw', padx=5, pady=10)
b_start.grid(row=12, column=0, sticky='sw', padx=5, pady=10)
b_pause.grid(row=12, column=1, sticky='sw', padx=5, pady=10)
b_tfm.grid(row=12, column=2, sticky='sw', padx=5, pady=10)
r_normal.grid(row=4, column=0, sticky='w', padx=5, pady=1)
r_fast.grid(row=5, column=0, sticky='w', padx=5, pady=1)
r_slow.grid(row=6, column=0, sticky='w', padx=5, pady=1)
r_buyonly.grid(row=8, column=0, sticky='w', padx=5, pady=1)
r_fullroutine.grid(row=9, column=0, sticky='w', padx=5, pady=1)
r_buysellfixed.grid(row=10, column=0, sticky='w', padx=5, pady=1)
t_outputbox.grid(row=13, column=0, columnspan=13, rowspan=13, sticky='nsew', padx=5, pady=10)
Notable differences:
I had to set a background color to make up for how we are moving that image.
The image is no longer using .place and instead using .grid.
The image will need to be resized a bit differently because it is a smaller area.
I removed all those row_configures because they were removing some rigidity, you can add it back if you like, but you'll have to re-scale your columns to match the new layout.
Let us know if you have any questions etc.
Complete noob here, I'm trying to submit data from a group of tkinter entry boxes to sqlite3. When I run the code, the form displays correctly and the table is created, but the data is not being submitted to the database. I get an error saying that "submit_record", the function connected to the submit button, is not defined. I've tried everything I know or could find online. Please help if you can. Been struggling with this one thing for 2 weeks! Thanks.
from tkinter import *
from tkinter import ttk
import sqlite3
LARGE_FONT = ('Veranda', 12)
MED_FONT = ('Veranda', 10, 'bold')
SMALL_FONT = ('Helvetica', 9, 'bold')
class CACFP_DB:
def setup_db(self):
# Open db
self.conn = sqlite3.connect('cacfp_test.db')
# Create a cursor
self.c = self.conn.cursor()
# Create the table if it doesn't exist
try:
self.c.execute("CREATE TABLE if not exists Staffing(ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, lname TEXT NOT NULL, fname TEXT NOT NULL, title TEXT NOT NULL, department TEXT NOT NULL, payType TEXT NOT NULL, start INTEGER NOT NULL, end_dt INTEGER NOT NULL, t_hours INTEGER NOT NULL, perinc REAL NOT NULL, inc_type TEXT NOT NULL, inc_date INTEGER NOT NULL, hrs_month INTEGER NOT NULL, month_yr INTEGER NOT NULL, c_hours REAL NOT NULL, per_c_hours REAL NOT NULL, gross_hrly REAL NOT NULL, gross_hrly_entry REAL NOT NULL, emp_tax REAL NOT NULL, ue_tax REAL NOT NULL, total_tax REAL NOT NULL, cost_per_emp REAL NOT NULL, cost_total TEXT NOT NULL);")
self.conn.commit()
except sqlite3.OperationalError:
print("ERROR: Table not Created")
def submit_record(self):
# Insert record into the db
staff_dtls = [self.lname_entry.get(), self.fname_entry.get(), self.title_entry.get(),
self.department_entry.get(), self.payType_entry.get(), self.start_entry.get(),
self.end_dt_entry.get(), self.t_hours_entry.get(), self.perinc_entry.get(),
self.inc_type.get(), self.inc_date_entry.get(), self.hrs_month_entry.get(),
self.month_yr_entry.get(), self.c_hours_entry.get(), self.per_c_hours_entry.get(),
self.gross_hrly_entry.get(), self.gross_monthly_entry.get(), self.emp_tax_entry.get(),
self.ue_tax_entry.get(), self.total_tax_entry.get()]
for element in staff_dtls:
c.excecute("INSERT INTO staffing VALUES (?)", (element))
self.conn.commit()
self.c.close()
self.conn.close()
def __init__(self, root):
root.title('CACFP (CACFP_developmant_version.py)')
root.geometry('1200x600')
root.state('zoomed')
mainlabel = ttk.Label(root, text='\nBudget Detail Worksheet', font=LARGE_FONT, justify=CENTER)
mainlabel.grid(row=0, column=0, columnspan=50, padx=5, sticky=W + E)
subtext = ttk.Label(root, text='Sponsors and Affiliated Sites')
subtext.grid(row=1, column=0, padx=5, sticky=W + E)
filler = ttk.Label(root, text='------')
filler.grid(row=3, column=0, padx=25)
# ----- Create Notebook -----#
nb = ttk.Notebook(root)
nb.grid(row=3, column=0, columnspan=50, rowspan=49, padx=5, pady=5, sticky='NESW')
# ----- Notebook Tab1 -----#
tab1 = ttk.Frame(nb)
nb.add(tab1, text='Staffing')
# tab1.grid_columnconfigure(8, minsize=10)
# ----- Tab1 Headings (row 0) ----- #
emp_head = ttk.Label(tab1, text='\nEMPLOYEE DETAILS', font=MED_FONT)
emp_head.grid(row=0, column=0, columnspan=12, sticky=W + E)
# ---- Frames (boxes) within tab1 ------
box1 = ttk.Frame(tab1, width=600, height=75, relief='raised', borderwidth='1')
box1.grid(row=1, column=0, padx=10, pady=20, sticky=W)
box2 = ttk.Frame(tab1, width=600, height=75, relief='raised', borderwidth='1')
box2.grid(row=3, column=0, padx=10, pady=20, sticky=W)
# ---- Box 1 labels and entry boxes -----
lname = ttk.Label(box1, text='\nLast Name', font=SMALL_FONT, justify=CENTER)
lname.grid(row=1, column=0, padx=2, pady=5, sticky='W')
lname_entry_value = StringVar(box1, value="")
lname_entry = ttk.Entry(box1, textvariable=lname_entry_value)
lname_entry.grid(row=2, column=0, padx=2, pady=5, sticky=W)
fname = ttk.Label(box1, text='\nFirst Name', font=SMALL_FONT, justify=CENTER)
fname.grid(row=1, column=1, padx=2, pady=5, sticky='W')
fname_entry_value = StringVar(box1, value="")
fname_entry = ttk.Entry(box1, textvariable=fname_entry_value)
fname_entry.grid(row=2, column=1, padx=2, pady=5, sticky=W)
title = ttk.Label(box1, text='\nPosition Title', font=SMALL_FONT, justify=CENTER)
title.grid(row=1, column=2, padx=2, pady=5, sticky='W')
title_entry_value = StringVar(box1, value="")
title_entry = ttk.Entry(box1, textvariable=title_entry_value)
title_entry.grid(row=2, column=2, padx=2, pady=5, sticky=W)
department = ttk.Label(box1, width=15, text='\nDeptartment', font=SMALL_FONT, justify=CENTER)
department.grid(row=1, column=3, padx=2, pady=5, sticky='W')
department_entry_value = StringVar(box1, value="")
department_entry = ttk.Entry(box1, textvariable=department_entry_value)
department_entry.grid(row=2, column=3, padx=2, pady=5, sticky='W')
payType = ttk.Label(box1, width=15, text='Pay Type\n(Hourly or Monthly)', font=SMALL_FONT, justify=CENTER)
payType.grid(row=1, column=4, padx=2, pady=5, sticky='W')
payType_entry_value = StringVar(box1, value="")
payType_entry = ttk.Entry(box1, textvariable=payType_entry_value)
payType_entry.grid(row=2, column=4)
start = ttk.Label(box1, text='\nStart Time', font=SMALL_FONT, justify=CENTER)
start.grid(row=1, column=5, padx=5, pady=5, sticky='W')
start_entry_value = StringVar(box1, value="")
start_entry = ttk.Entry(box1, width=12, textvariable=start_entry_value)
start_entry.grid(row=2, column=5, padx=2, pady=5, sticky=W)
end_dt = ttk.Label(box1, text='\nEnd Time', font=SMALL_FONT, justify=CENTER)
end_dt.grid(row=1, column=6, padx=5, pady=5, sticky='W')
end_dt_entry_value = StringVar(box1, value="")
end_dt_entry = ttk.Entry(box1, width=12, textvariable=end_dt_entry_value)
end_dt_entry.grid(row=2, column=6, padx=2, pady=5, sticky=W)
t_hours = ttk.Label(box1, text='Total Work\nHours', font=SMALL_FONT, justify=CENTER)
t_hours.grid(row=1, column=7, padx=5, pady=5, sticky='W')
t_hours_entry_value = IntVar(box1, value="")
t_hours_entry = ttk.Entry(box1, width=12, textvariable=t_hours_entry_value)
t_hours_entry.grid(row=2, column=7, padx=2, pady=5, sticky=W)
perinc = ttk.Label(box1, width=10, text='Annual %\nIncrease', font=SMALL_FONT, justify=CENTER)
perinc.grid(row=1, column=8, padx=5, pady=5, sticky='W')
perinc_entry_value = StringVar(box1, value="")
perinc_entry = ttk.Entry(box1, width=12, textvariable=perinc_entry_value)
perinc_entry.grid(row=2, column=8, padx=2, pady=5, sticky=W)
inc_type = ttk.Label(box1, text='Increase Type\n(Merit or COL)', font=SMALL_FONT, justify=CENTER)
inc_type.grid(row=1, column=9, padx=2, pady=5, sticky='W')
inc_type_entry_value = StringVar(box1, value="")
inc_type_entry = ttk.Entry(box1, width=15, textvariable=inc_type_entry_value)
inc_type_entry.grid(row=2, column=9)
inc_date = ttk.Label(box1, text='Increase\nDate', font=SMALL_FONT, justify=CENTER)
inc_date.grid(row=1, column=10, padx=5, pady=5, sticky='W')
inc_date_entry_value = StringVar(box1, value="")
inc_date_entry = ttk.Entry(box1, width=14, textvariable=inc_date_entry_value)
inc_date_entry.grid(row=2, column=10, padx=2, pady=5, sticky=W)
# ---- Box 2 labels and entry boxes for tab1 -----
hrs_month = ttk.Label(box2, text='Total Work\nHrs/Month', font=SMALL_FONT, justify=CENTER)
hrs_month.grid(row=1, column=0, padx=5, pady=5, sticky='W')
hrs_month_entry_value = StringVar(box2, value="")
hrs_month_entry = ttk.Entry(box2, width=12, textvariable=hrs_month_entry_value)
hrs_month_entry.grid(row=2, column=0, padx=2, pady=5, sticky=W)
month_yr = ttk.Label(box2, text='Total Work\nMonths/Yr', font=SMALL_FONT, justify=CENTER)
month_yr.grid(row=1, column=1, padx=5, pady=5, sticky='W')
month_yr_entry_value = StringVar(box2, value="")
month_yr_entry = ttk.Entry(box2, width=12, textvariable=month_yr_entry_value)
month_yr_entry.grid(row=2, column=1, padx=2, pady=5, sticky=W)
c_hours = ttk.Label(box2, text='Total Hrs Worked\nfor CACFP', font=SMALL_FONT, justify=CENTER)
c_hours.grid(row=1, column=2, padx=2, pady=5, sticky='W')
c_hours_entry_value = StringVar(box2, value="")
c_hours_entry = ttk.Entry(box2, textvariable=c_hours_entry_value)
c_hours_entry.grid(row=2, column=2, padx=2, pady=5, sticky=W)
per_c_hours = ttk.Label(box2, text='% Hrs Worked\nfor CACFP', font=SMALL_FONT, justify=CENTER)
per_c_hours.grid(row=1, column=3, padx=2, pady=5, sticky='W')
per_c_hours_entry_value = StringVar(box2, value="")
per_c_hours_entry = ttk.Entry(box2, textvariable=per_c_hours_entry_value)
per_c_hours_entry.grid(row=2, column=3, padx=2, pady=5, sticky=W)
gross_hrly = ttk.Label(box2, text='Gross Hourly\n(before deductions)', font=SMALL_FONT, justify=CENTER)
gross_hrly.grid(row=1, column=4, padx=5, pady=5, sticky='W')
gross_hrly_entry_value = StringVar(box2, value="")
gross_hrly_entry = ttk.Entry(box2, textvariable=gross_hrly_entry_value)
gross_hrly_entry.grid(row=2, column=4, padx=2, pady=5, sticky=W)
gross_monthly = ttk.Label(box2, text='Gross Monthly\n(before deductions)', font=SMALL_FONT, justify=CENTER)
gross_monthly.grid(row=1, column=5, padx=5, pady=5, sticky='W')
gross_monthly_entry_value = StringVar(box2, value="")
gross_monthly = ttk.Entry(box2, textvariable=gross_monthly_entry_value)
gross_monthly.grid(row=2, column=5, padx=2, pady=5, sticky=W)
emp_tax = ttk.Label(box2, text='Employer Tax\nPer Month', font=SMALL_FONT, justify=CENTER)
emp_tax.grid(row=1, column=6, padx=5, pady=5, sticky='W')
emp_tax_entry_value = StringVar(box2, value="")
emp_tax = ttk.Entry(box2, textvariable=emp_tax_entry_value)
emp_tax.grid(row=2, column=6, padx=2, pady=5, sticky=W)
ue_tax = ttk.Label(box2, text='Unemployment\nTax Rate/Month', font=SMALL_FONT, justify=CENTER)
ue_tax.grid(row=1, column=7, padx=5, pady=5, sticky='W')
ue_tax_entry_value = StringVar(box2, value="")
ue_tax = ttk.Entry(box2, textvariable=ue_tax_entry_value)
ue_tax.grid(row=2, column=7, padx=2, pady=5, sticky=W)
total_tax = ttk.Label(box2, text='Total Tax Paid\nPer Month', font=SMALL_FONT, justify=CENTER)
total_tax.grid(row=1, column=8, padx=5, pady=5, sticky='W')
total_tax_entry_value = StringVar(box2, value="")
total_tax = ttk.Entry(box2, textvariable=total_tax_entry_value)
total_tax.grid(row=2, column=8, padx=2, pady=5, sticky=W)
cost_per_emp = ttk.Label(box2, width=13, text='Annual Cost\nto CACFP', font=SMALL_FONT, justify=CENTER)
cost_per_emp.grid(row=1, column=9)
cost_per_emp = ttk.Label(box2, width=12, text='$ 00,000.00', relief=SUNKEN, borderwidth=0)
cost_per_emp.grid(row=2, column=9, padx=2, pady=5, sticky=W)
cost_per_emp.configure(background='white')
# ----- Root Command Bar (works with tab1 data)
cmd_bar = ttk.Frame(root, width=150, height=615, relief='raised', borderwidth='2')
cmd_bar.grid(row=6, column=100, sticky=NSEW)
cmd_bar_title = ttk.Label(cmd_bar, text='Command Bar', font=MED_FONT, justify=CENTER)
cmd_bar_title.grid(row=0, column=0, pady=5, padx=10, sticky=N)
cmd_bar.grid_propagate(0)
# ----- Action Buttons -----
submit_1 = ttk.Button(cmd_bar, text='Submit', command=lambda: self.submit_record())
submit_1.grid(row=3, column=0, pady=15)
# # ----- End Tab1 Detail Labels ----- #
self.setup_db()
root = Tk()
db = CACFP_DB(root)
root.mainloop()
You have in your code more inconsistencies.
Firstly, when you have in staff_dtls e.g. self.lname_entry.get(), you have to have defined self.lname_entry, it's not sufficient to have only lname_entry, because of Python Classes and OOP theory.
Next, you have some mess in variable names e.g. in staff_dtls you have self.inc_type.get(), but you have to have self.inc_type_entry.get() and vice versa, you have e.g.
ue_tax = ttk.Entry(box2, textvariable=ue_tax_entry_value), but you need ue_tax_entry = ttk.Entry(box2, textvariable=ue_tax_entry_value). So unite precisely your variable names.
Next, instead of c.excecute("INSERT INTO staffing VALUES (?)", (element)) (with typo excecute), you need something like this self.c.execute("INSERT INTO staffing VALUES (?, ?, ?, ?, ?, ?, ...)", (element)), with so many question marks, how many columns you want to insert to DB.
These are the main errors when you fix them, you will be on the right track.
I have a Toplevel Window with one grid row containing a Label, Entry and a "+" Button (window on startup)
When I hit the Add-Button a new row with the same content is generated. But the problem is, that the window doesn't resize and fit to its new contents. Should look like this resized window.
The code is below:
def process_map():
numbers = {0:'\u2080', 1:'\u2081', 2:'\u2082', 3:'\u2083', 4:'\u2084', 5:'\u2085', 6:'\u2086', 7:'\u2087', 8:'\u2088', 9:'\u2089'}
button_pos = tk.IntVar(0)
ENTRIES = {}
def add_button():
if button_pos.get() >= 10:
index = numbers[button_pos.get()//10] + numbers[button_pos.get()%10]
else:
index = numbers[button_pos.get()]
lb = tk.Label(top_root, text='\u03C6'+index)
lb.grid(row=button_pos.get(), column=0, sticky='NWES')
entry = tk.Entry(top_root, width=4, relief='sunken', bd=2)
entry.grid(row=button_pos.get(), column=1, sticky='WE', padx=5, pady=5)
ENTRIES.update({button_pos.get():entry})
bt.grid(row=button_pos.get(), column=2, sticky='WE', padx=5, pady=5)
bt_close.grid(row=button_pos.get()+1, column=1, padx=5, pady=5)
bt_start.grid(row=button_pos.get()+1, column=0, padx=5, pady=5)
button_pos.set(button_pos.get()+1)
center(top_root)
top_root = tk.Toplevel(root)
top_root.title('Select \u03C6')
lb = tk.Label(top_root, text='\u03C6\u2081', height=1)
lb.grid(row=0, column=0, sticky='NWES')
entry = tk.Entry(top_root, width=4, relief='sunken', bd=2)
entry.grid(row=0, column=1, sticky='WE', padx=5, pady=5)
button_pos.set(button_pos.get()+2)
ENTRIES.update({button_pos.get():entry})
bt = tk.Button(top_root, text='+', command=add_button,)
bt.grid(row=0, column=2, sticky='WE', padx=5, pady=5)
bt_close = tk.Button(top_root, text='Cancel', width=15, command=top_root.destroy)
bt_close.grid(row=button_pos.get()+1, column=1, padx=5, pady=5)
bt_start = tk.Button(top_root, text='Start', width=15)
bt_start.grid(row=button_pos.get()+1, column=0, padx=5, pady=5)
center(top_root)
top_root.mainloop()