Executable using tkinter and multiprocessing creates multiple windows - python

I have built a gui for a script using tkinter.
I have tried building an executable with both cx_freeze and pyinstaller.
I make extensive use of scipy, numpy, statsmodels and matplotlib
Whenever I click the "Run" button, it spawns another window and the window beneath it stops responding. This can occur seemingly indefinitely.
I do use multiprocessing in my application, but I fixed the multiple windows issue in the python script version
How do I fix the multiple windows issue in my standalone program?
If there is not a reasonable fix, is there another way to package the program for use? Maybe a custom Python distribution?
from tkinter import *
from tkinter import ttk
def run():
import multiprocessing
import risers_fallers
import time
time_periods = list()
time_periods.append(month.get())
time_periods.append(threemonth.get())
time_periods.append(sixmonth.get())
time_periods.append(year.get())
#print(infile.get(), time_periods, filter_val.get(), outfile.get())
#loading screen
toplevel = Toplevel()
toplevel.focus_force()
loading = Label(toplevel, text = "RUNNING")#PhotoImage(file= photopath, format="gif - {}")
loading.pack()
subproc = multiprocessing.Process(target = risers_fallers.risers_fallers, args = (infile.get(), time_periods, filter_val.get(), outfile.get(),
top_x.get(), excel.get(), tableau.get(), onecat.get(), multicat.get(), external.get()))
subproc.start()
subproc.join()
toplevel.destroy()
def browsecsv():
from tkinter import filedialog
Tk().withdraw()
filename = filedialog.askopenfilename()
#print(filename)
infile.set(filename)
if __name__ == "__main__":
#initialize tk
root = Tk()
#set title
root.title("FM Risers and Fallers")
#create padding, new frame, configure columns and rows
#mainframe = ttk.Frame(root, padding="3 3 12 12")
#our variables
month = BooleanVar()
threemonth = BooleanVar()
sixmonth = BooleanVar()
year = BooleanVar()
excel = BooleanVar()
tableau = BooleanVar()
onecat = BooleanVar()
multicat = BooleanVar()
external = BooleanVar()
top_x = StringVar()
top_x.set("15")
infile = StringVar()
outfile = StringVar()
filter_val = StringVar()
photopath = "./41.gif"
#default values
filter_val.set("30")
import datetime
from re import sub
d = datetime.datetime.now()
outfile.set(sub('[^0-9|\s]',' ', str(d)))
"""
our widgets
"""
#labels for tab 1 Not needed with pane view
# ttk.Label(mainframe, text="Input file") #.grid(column=3, row=1, sticky=W)
# ttk.Label(mainframe, text="Output name") #.grid(column=3, row=1, sticky=W)
# ttk.Label(mainframe, text="Dashboard period of times") #.grid(column=3, row=1, sticky=W)
# ttk.Label(mainframe, text="Filter by growth rate") #.grid(column=3, row=1, sticky=W)
master = Frame(root, name = 'master')
master.pack(fill=BOTH)
#notebook container
notebook = ttk.Notebook(master)
notebook.pack(fill=BOTH, padx=2, pady=3)
tab0 = ttk.Frame(notebook)
tab1 = ttk.Frame(notebook)
tab2 = ttk.Frame(notebook)
notebook.add(tab0, text='Risers and Fallers')
notebook.add(tab1, text='Help')
notebook.add(tab2, text='About')
#tab 1 panes
panel_0 = ttk.Panedwindow(tab0, orient=VERTICAL)
file_pane_0 = ttk.Labelframe(panel_0, text='Input and Output', width = 300, height=100)
dashboard_pane_0 = ttk.Labelframe(panel_0, text='Dashboard Time Period', width = 300, height=200)
filter_pane_0 = ttk.Labelframe(panel_0, text='Filter by Growth Rate', width = 300, height=200)
run_frame_0 = Frame(panel_0, width = 300, height=100)
output_options_frame = ttk.Labelframe(panel_0, text='Output Options', width = 300, height=200)
top_x_frame_0 = ttk.Labelframe(panel_0, text = "Number of Risers", width = 300, height=100)
#grid it
panel_0.pack(fill=BOTH, expand=1)
file_pane_0.grid(row = 0, column = 0, columnspan = 3)
dashboard_pane_0.grid(row = 1, column = 0)
filter_pane_0.grid(row = 2, column = 0)
output_options_frame.grid(row = 1, column = 1)
top_x_frame_0.grid(row = 2, column = 1)
#pack em!
# panel_0.pack(fill=BOTH, expand=1)
# file_pane_0.pack(fill=X, expand=1)
# dashboard_pane_0.pack(side = LEFT, fill = Y)
# filter_pane_0.pack(side = RIGHT, fill = Y)
# top_x_frame_0.pack(fill=BOTH, expand=1)
#tab 2 panes
panel_1 = ttk.Panedwindow(tab1, orient=VERTICAL)
file_pane_1 = ttk.Labelframe(panel_1, text='Input and Output', width = 300, height=100)
dashboard_pane_1 = ttk.Labelframe(panel_1, text='Dashboard Time Period', width = 300, height=300)
filter_pane_1 = ttk.Labelframe(panel_1, text='Filter by Growth Rate', width = 300, height=300)
#pack em!
panel_1.pack(fill=BOTH, expand=1)
file_pane_1.pack(fill=BOTH, expand=1)
dashboard_pane_1.pack(side = LEFT, fill = Y)
filter_pane_1.pack(side = RIGHT, fill = Y)
#tab 3 panes
panel_2 = ttk.Panedwindow(tab2, orient=VERTICAL)
about_pane = ttk.Labelframe(panel_2, text='About', width = 300, height=200)
description_pane = ttk.Labelframe(panel_2, text='Description', width = 300, height=200)
citation_pane = ttk.Labelframe(panel_2, text='Citations', width = 300, height=200)
#pack em!
panel_2.pack(fill=BOTH, expand=1)
about_pane.pack(fill=BOTH, expand=1)
description_pane.pack(fill=BOTH, expand=1)
citation_pane.pack(fill=BOTH, expand=1)
#labels for tab 2 (help)
dashboard_help = ttk.Label(dashboard_pane_1, text= """Choose what units of
time to create a
dashboard for.
Note that time
periods are most
recent, not a
defined quarter or
calendar year.""")
io_help = ttk.Label(file_pane_1, text="""Output file: the first words to use in the naming of the output files
Input file: the BW output that you want to analyze.
See documentation for required format.""")
dashboard_help.pack()
io_help.pack(fill = BOTH)
#labels for tab 3 (about)
about_section = ttk.Label(about_pane, text="""The FM Risers and Fallers project was created by Jeremy Barnes
from May 2016 - July 2016 as a way to identify highest growing
parts.
Business logic was created based upon discussions with
Daniel DiTommasso, David Enochs, Alex Miles
and Robert Pietrowsky.
""")
description_section = ttk.Label(description_pane, text="""The FM Risers and Fallers application loads BW output from a
specific format, performs seasonal adjustment on the data,
derives information from the dataand then outputs all
derived information and dashboards with ranking information.
""")
citations_section = ttk.Label(citation_pane, text="""The FM Risers and Fallers project was created using
x13-ARIMA-SEATS by the US Census Bureau
pandas
statsmodels
Download links are available in the documentation
""")
#pack em
about_section.pack(fill=BOTH, expand=1)
description_section.pack(fill=BOTH, expand=1)
citations_section.pack(fill=BOTH, expand=1)
#file entry
#output
#output = Frame(file_pane_0, width = 300, height=50)
output_label = ttk.Label(file_pane_0, text="Output file").grid(column=1, row=1, sticky=W)
outfile_entry = ttk.Entry(file_pane_0, width = 50, textvariable = outfile).grid(column=2, row=1, sticky=W)
# output.pack(side = TOP, fill = X)
# output_label.pack(side = LEFT)
# outfile_entry.pack(side = RIGHT)
#input
#input = Frame(file_pane_0, width = 300, height=50)
input_label = ttk.Label(file_pane_0, text="Input file").grid(column=1, row=2, sticky=W)
infile_entry = ttk.Entry(file_pane_0, width = 50, textvariable = infile).grid(column=2, row=2, sticky=W)
#cbutton.grid(row=10, column=3, sticky = W + E)
bbutton= Button(file_pane_0, text="Browse", command= browsecsv).grid(column = 3, row = 2)
# input.pack(side = BOTTOM, fill = X)
# input_label.pack(side = LEFT)
# infile_entry.pack(side = RIGHT)
#top_x
top_x_label = ttk.Label(top_x_frame_0, text="Risers/Fallers to identify").grid(column=1, row=2, sticky=W)
top_x_entry = ttk.Entry(top_x_frame_0, width = 7, textvariable = top_x).grid(column=2, row=2, sticky=W)
#dashboard times
monthly = Checkbutton(dashboard_pane_0, text = "Month", variable = month).grid(row = 1, sticky=W, pady=1)
threemonthly = Checkbutton(dashboard_pane_0, text = "3 Months", variable = threemonth).grid(row = 2, sticky=W, pady=1)
sixmonthly = Checkbutton(dashboard_pane_0, text = "6 Months", variable = sixmonth).grid(row = 3, sticky=W, pady=1)
yearly = Checkbutton(dashboard_pane_0, text = "Year", variable = year).grid(row = 4, sticky=W, pady=1)
#output options
excel_button = Checkbutton(output_options_frame, text = "Excel", variable = excel).grid(row = 1, sticky=W, pady=1)
tableau_button = Checkbutton(output_options_frame, text = "Tableau", variable = tableau).grid(row = 2, sticky=W, pady=1)
onecat_button = Checkbutton(output_options_frame, text = "One Category", variable = onecat).grid(row = 3, sticky=W, pady=1)
multicat_button = Checkbutton(output_options_frame, text = "Many Categories", variable = multicat).grid(row = 4, sticky=W, pady=1)
external_button = Checkbutton(output_options_frame, text = "External Report", variable = external).grid(row = 5, sticky=W, pady=1)
#growth rate stuff
growth_input_label = ttk.Label(filter_pane_0, text="Analyze only top: ").grid(row = 1, column = 1, sticky=W, pady = 4, padx = 4)
growth_input = ttk.Entry(filter_pane_0, width = 7, textvariable = filter_val).grid(row = 1, column = 2, sticky=W, pady = 4, padx = 4)
# Radiobutton(filter_pane_0, text = "Standard Deviations", variable = stddev, value = 1).grid(row = 2, column = 1, sticky=W, pady = 4)
# Radiobutton(filter_pane_0, text = "Percentage", variable = stddev, value = 0).grid(row = 2, column = 2, sticky=W, pady = 4)
#growth_default_label = ttk.Label(filter_pane_0, text="(Leave blank for default").grid(row = 3, column = 1, sticky=W, pady = 4, padx = 4)
percent_label = ttk.Label(filter_pane_0, text=" %").grid(row = 1, column = 3, sticky=W, pady = 4, padx = 4)
#launch button
run_buttom_frame = Frame(panel_0, width = 300, height=50)
run_button = Button(run_buttom_frame, text = "RUN ANALYSIS", command = run)
run_button.pack()
run_buttom_frame.grid(row = 3, column = 0, columnspan = 2, pady = 4)
root.mainloop()

Two processes or more can't share a single root window. Every process that creates a widget will get its own window.

I managed to fix this with some experimentation.
It no longer launches multiple windows after I made the business logic launch within the same process.

Related

How to access text inside an Entry widget from a function in tkinter?

I have a python GUI assignment in which I have to create a GUI application which will evaluate a single variable function within a specified range of input values. We have to use classes. I have written the following code:
from tkinter import *
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
import tkinter.font as font
class eval_interface:
def __init__(self):
self.root = Tk()
self.root.title("Function Evaluator")
self.topframe = Frame(self.root)
self.createTopFrame()
self.topframe.grid(row=0, column=0, columnspan=10, sticky=N + S + W + E)
self.frame2 = Frame(self.root)
self.createFrame2()
self.frame2.grid(row = 1, column = 0, pady = 15, columnspan = 10, sticky = N + S + W + E)
self.frame3 = Frame(self.root)
self.createFrame3()
self.frame3.grid(row=2, column=0, pady=15, columnspan=10, sticky=N + S + W + E)
self.frame4 = Frame(self.root)
self.frame5 = Frame(self.root)
self.createFrame5()
self.frame5.grid(row=4, column=0, pady=15, columnspan=10, sticky=N + S + E + W)
self.createFrame4()
self.frame4.grid(row = 3, column = 0, pady = 15, columnspan = 10, sticky = N+S+E+W)
self.root.mainloop()
def createTopFrame(self): #Frame containing title
title = Label(self.topframe, text="Function evaluator and plotter".center(228, " "), font=font.Font(size=17))
title.grid(row=0, column=0, columnspan=7)
def createFrame2(self): #Frame containing function Entry widget
title = Label(self.frame2, text = "Enter the function in x : ", font = font.Font(size = 14))
title.grid(row = 0, column = 0, sticky = N + S + W + E)
function_entry = Entry(self.frame2, width = 150)
function_entry.grid(row = 0, column = 1, sticky = N + S + W + E)
def createFrame3(self): #Frame containing range Entry widgets
range_label = Label(self.frame3, text="Enter the range of the function from : ", font = font.Font(size = 14))
lower_range_entry = Entry(self.frame3, width=10)
range_label2 = Label(self.frame3, text=" to ")
upper_range_entry = Entry(self.frame3, width=10)
range_label.grid(row=1, column=0, sticky="nsew")
lower_range_entry.grid(row=1, column=1)
range_label2.grid(row=1, column=2, sticky="nsew")
upper_range_entry.grid(row=1, column=3, sticky="nsew")
def createFrame4(self): #Frame containing button widgets
btn_evaluate = Button(self.frame4, text = "Evaluate", font = font.Font(size = 14), command = self.evaluate())
btn_plot = Button(self.frame4, text = "Plot", font = font.Font(size = 14))
btn_clear = Button(self.frame4, text = "Clear", font = font.Font(size = 14))
btn_exit = Button(self.frame4, text = "Exit", font = font.Font(size = 14), command = exit)
btn_evaluate.grid(row=0, column=0, padx=10, pady=5)
btn_plot.grid(row=0, column=1, padx=10, pady=5)
btn_clear.grid(row=0, column=2, padx=10, pady=5)
btn_exit.grid(row=0, column=3, padx=10, pady=5)
def createFrame5(self): #Frame containing Result Textbox
res_text = Text(self.frame5, width = 95, height = 55, padx = 10)
res_text.grid(row = 0, column = 0)
def evaluate(self):
x = 10
def clear(self):
z=12
eval_interface()
My question is, how do I access the data inputted by the user in the three entry widgets (in frames 2 and 3) when the Evaluate button is clicked? And after I have accessed the data and done the necessary operations on it, how do I display the result in the Textbox in Frame 5? (I have just coded some random statement in evaluate and clear functions for now to see the output GUI.)
If you want to access the Entry widgets inside evaluate() function, you need to change the three local variables function_entry, lower_range_entry and upper_range_entry to instance variables self.function_entry, self.lower_range_entry and self.upper_range_entry. Same for the Text widget res_text. Then you can get the values from the three Entry widgets and insert the result into self.res_text inside evaluate() function:
def createFrame2(self): #Frame containing function Entry widget
title = Label(self.frame2, text = "Enter the function in x : ", font = font.Font(size = 14))
title.grid(row = 0, column = 0, sticky = N + S + W + E)
self.function_entry = Entry(self.frame2, width = 150)
self.function_entry.grid(row = 0, column = 1, sticky = N + S + W + E)
def createFrame3(self): #Frame containing range Entry widgets
range_label = Label(self.frame3, text="Enter the range of the function from : ", font = font.Font(size = 14))
self.lower_range_entry = Entry(self.frame3, width=10)
range_label2 = Label(self.frame3, text=" to ")
self.upper_range_entry = Entry(self.frame3, width=10)
range_label.grid(row=1, column=0, sticky="nsew")
self.lower_range_entry.grid(row=1, column=1)
range_label2.grid(row=1, column=2, sticky="nsew")
self.upper_range_entry.grid(row=1, column=3, sticky="nsew")
...
def createFrame5(self): #Frame containing Result Textbox
self.res_text = Text(self.frame5, width = 95, height = 55, padx = 10)
self.res_text.grid(row = 0, column = 0)
def evaluate(self):
# get content from entries
x = self.function_entry.get()
lower = self.lower_range_entry.get()
upper = self.upper_range_entry.get()
# example on inserting result into text box
result = ", ".join([x, lower, upper]) # or whatever you want
self.res_text.insert("end", result)
...
Also command=self.evaluate() inside createFrame4() should be command=self.evaluate instead.

RE: TKinter Table Row Deletion (PYTHON)

(If anyone has seen my previous question, I found a way to save the row indexes and use them in the delete function :3)
Is there a way to stop/delete a running function/table on a button click? I am making a simple customer registration program which saves data from text fields (cID, custName, custEmail, and custBday) and deletes a selected row. My problem is that whenever I delete a row, the last row somehow leaves/lags behind creating this duplicate whenever a row is deleted. Any suggestions or is there something I've done wrong or I've missed?
My Code:
from tkinter import *
from tkinter import messagebox
import tkinter as tk
at = False
dotcom = False
list = [['ID', 'NAME', 'EMAIL', 'BIRTHDATE']]
recentIndex = []
ID = 1
storedIndex = 0
def callback(event):
custid.config(state=NORMAL)
custid.delete('1.0', END)
custid.insert(1.0, list[event.widget._values][0])
custid.config(state=DISABLED)
cName.set(list[event.widget._values][1])
cEmail.set(list[event.widget._values][2])
birthdate.set(list[event.widget._values][3])
indexPosition = event.widget._values
recentIndex.append(indexPosition)
print(recentIndex)
def createTable():
for i in range(len(list)):
for j in range(len(list[0])):
mgrid = tk.Entry(window, width = 10, bg= 'yellow')
mgrid.insert(tk.END, list[i][j])
mgrid._values= i
mgrid.grid (row = i + 5,column = j + 5)
mgrid.bind("<Button-1>", callback)
def delete():
try:
list.pop(recentIndex[-1])
if recentIndex[-1] > 0 or NONE:
msgbox("Data Delete", "Record")
createTable()
else:
msgbox("No Data Selected", "record")
return
except:
msgbox("No Data Selected", "record")
def save ():
custid.config(state= NORMAL)
initialValue = int(custid.get('1.0', END))
custid.delete('1.0', END)
list.append([ID, custName.get(), custEmail.get(), custBday.get()])
custid.insert(1.0, initialValue + 1)
custid.config(state=DISABLED)
createTable()
msgbox("Saved", "Record")
ID = ID + 1
def msgbox (msg, titlebar):
messagebox.showinfo(title = titlebar, message=msg)
def products():
window = Tk()
window.title("Products Form")
window.geometry("550x400")
window.configure(bg="orange")
window = Tk()
window.title("Sample Window")
window.geometry("550x400")
window.configure(bg="orange")
menubar = Menu(window)
filemenu = Menu(menubar, tearoff=0)
menubar.add_cascade(label="File", menu=filemenu)
filemenu.add_command(label="Products", command=products)
filemenu.add_command(label="Orders")
filemenu.add_separator()
filemenu.add_command(label="Close", command = window.quit)
window.config(menu=menubar)
labelTitle = Label(window, text="Customer Registration System", width=30, height=1, bg="yellow", anchor= "center")
labelTitle.config(font=("Courier", 10))
labelTitle.grid(column=2, row=1)
labelID = Label(window, text="Customer ID", width = 20, height = 1, bg = "yellow")
labelID.grid(column=1, row=2)
cID = StringVar()
custid = Text(window, width=15, height=1)
custid.grid(column=2, row=2)
custid.insert(1.0, "1")
custid.config(state = DISABLED)
labelNameCheck = Label(window, text="Last Name, First Name", width = 20, height = 1, bg = "yellow")
labelNameCheck.grid(column=3, row=3)
labelName = Label(window, text="Customer Name", width = 20, height = 1, bg = "yellow")
labelName.grid(column=1, row=3)
cName = StringVar()
custName = Entry(window, textvariable = cName)
custName.grid(column=2, row=3)
labelEmail = Label(window, text="Customer Email", width = 20, height = 1, bg = "yellow")
labelEmail.grid(column=1, row=4)
cEmail = StringVar()
custEmail = Entry(window, textvariable = cEmail)
custEmail.grid(column=2, row=4)
custEmail.bind("<KeyRelease>", keyup)
labelEmail = Label(window, text="[a-z]#[a-z].com", width = 20, height = 1, bg = "yellow")
labelEmail.grid(column=3, row=4)
labelBday = Label(window, text="Customer Birthdate", width = 20, height = 1, bg = "yellow")
labelBday.grid(column=1, row=5)
birthdate= StringVar()
custBday = Entry(window, textvariable = birthdate)
custBday.grid(column=2, row=5)
custBday.bind("<KeyRelease>", keyupBdate)
birthdateCheck = Label(window, text="mm/dd/yyyy", width = 20, height = 1, bg = "yellow")
birthdateCheck.grid(column=3, row=5)
savebtn = Button(text = "Save", command = save)
savebtn.grid(column=1)
deletebtn = Button(text = "Delete", command = delete)
deletebtn.grid(column=1)
window.mainloop()
You need to delete current displayed records before showing updated records inside createTable(). Also better create a frame for showing the records, so that it is more easier to clear the displayed records:
def createTable():
# clear current displayed records
for w in tableFrame.winfo_children():
w.destroy()
# populate records
for i in range(len(list)):
for j in range(len(list[0])):
mgrid = tk.Entry(tableFrame, width = 10, bg= 'yellow') # use tableFrame as parent
mgrid.insert(tk.END, list[i][j])
mgrid._values= i
mgrid.grid (row = i,column = j)
mgrid.bind("<Button-1>", callback)
...
# frame for showing records
tableFrame = Frame(window)
tableFrame.grid(row=5, column=5)
...

How do I add things with button in tkinter?

So, what i wanna do is that when i click the button, a new thing to be added to my project.
I have few tabs, and on the second one (WorkExp) I got Company and job description labels, and i want that whenever i click the button it to add new same labels.
it works, the button, but the thing is add the placement on these new labels is the same as old ones.
I tried while and for cycle but i couldnt make any of them work.
What I have tried:
WorkExp = ttk.Frame(Tabs)
Tabs.add(WorkExp, text = "Work Experience")
######################
def AddExp():
Label(WorkExp, text = "Company/Place", padx = 5, pady = 5).grid(row = 3, column = 1)
Label(WorkExp, text="Job Description", padx=5, pady=5).grid(row = 4 , column=1)
Comp2 = Entry(WorkExp).grid(row=3, column=2)
Work2 = Entry(WorkExp).grid(row=4, column=2)
######################
Label(WorkExp, text = "Company/Place", padx = 5, pady = 5).grid(row = 1, column = 1)
Label(WorkExp, text = "Job Description", padx = 5, pady = 5).grid(row = 2, column = 1)
Comp1 = Entry(WorkExp).grid(row = 1, column = 2)
Work1 = Entry(WorkExp).grid(row = 2, column = 2)
Button(WorkExp, text = "Add Experience", command = AddExp).grid(row = 10, column = 1)
import Tkinter as tk
# Now Start From Here
class App(object):
def new_row(self):
# Create widgets -----
new_entry = tk.Entry(root, width=7)
# Put widgets in grid----------
self.num_rows += 1
new_entry.grid(column=0, row=self.num_rows, sticky='WE')
def __init__(self):
self.num_rows = 1
createRow_button = tk.Button(
root, text='New Row', command=self.new_row)
createRow_button.grid()
root = tk.Tk()
app = App()
root.mainloop()

Entry() Is not showing up in my program

I am having trouble figuring out why my Entry() is not showing up in my program window. I have looked around the internet and I can not figure out what I am doing wrong.
I am trying to place my Entry() field above my main text filed in the program but at this point I would settle for it showing up at all in the program.
The code works fine except for the EntryWidget I am tying to add in.
from tkinter import *
from tkinter.ttk import *
import subprocess as sub
import tkinter.messagebox
#use the doNothing function as a holder for anything that needs to call a function you have not made yet
def doNothing():
print("Do lots of nothing?")
#~~~~~~~~~~~< Message Box >~~~~~~~~~~~
def ihnb():
tkinter.messagebox.showinfo("This is an example!", "Icecream Has No Bones!")
answer = tkinter.messagebox.askquestion("This is not a real question", "Are you trying to become a programer?")
if answer == "yes":
a1 = "Then be prepared to spend countless hours hating life!"
root.text.insert(tkinter.END, a1)
root.text.see(tkinter.END)
else:
a2= "Smart move. Now go away!"
root.text.insert(tkinter.END, a2)
root.text.see(tkinter.END)
#create the window
root = Tk()
#modify root window
root.title("MINT: Mobile Information & Note-taking Tool")
root.geometry("800x600")
root.config(bg = 'Orange')
#~~~~~~~~~~~< Entry Widget >~~~~~~~~~~~
keywordEntry = Entry(root)
keywordEntry.grid(row=3, column=1)
keywordEntry.delete(0, END)
keywordEntry.insert(END, 'default text')
#~~~~~~~~~~~< Menu >~~~~~~~~~~~
menu = Menu(root)
root.config(menu=menu)
fileMenu = Menu(menu)
menu.add_cascade(label="File", menu=fileMenu)
fileMenu.add_command(label="Save", command=doNothing)
fileMenu.add_command(label="Save As", command=doNothing)
fileMenu.add_separator()
fileMenu.add_command(label="Exit", command= doNothing)
helpMenu = Menu(menu)
menu.add_cascade(label="Help", menu=helpMenu)
helpMenu.add_command(label="Info", command=doNothing)
#~~~~~~~~~~~< Toolbar >~~~~~~~~~~~
spacer10 = " "
toolbar = Frame(root)
somethingButt = tkinter.Button(toolbar, fg = 'Black', bg = 'Orange', text = "Do Python?", command = ihnb)
somethingButt.grid(row = 0, column = 0, padx = 1, pady = 1, sticky = W)
buttonSpacer0_1 = tkinter.Button(toolbar, fg = 'Black', bg = 'Black', text = spacer10)
buttonSpacer0_1.grid(row = 0, column = 1, padx = 1, pady = 1, sticky = W)
somethingButt2 = tkinter.Button(toolbar, fg = 'White', bg = 'Black', text = "Do something?", command = doNothing)
somethingButt2.grid(row = 0, column = 2, padx = 1, pady = 1, sticky = W)
buttonSpacer0_1 = tkinter.Button(toolbar, fg = 'Black', bg = 'Black', text = spacer10)
buttonSpacer0_1.grid(row = 0, column = 3, padx = 1, pady = 1, sticky = W)
somethingButt3 = tkinter.Button(toolbar, fg = 'White', bg = 'Black', text = "Do something?", command = doNothing)
somethingButt3.grid(row = 0, column = 4, padx = 1, pady = 1, sticky = W)
toolbar.grid(row = 0, sticky = W)
#~~~~~~~~~~~< Toolbar >~~~~~~~~~~~
root.text = Text (root, width = 100, height = 10, fg='White', bg='Black', wrap = WORD)
root.text.grid(row = 10, padx=5, pady=5)
#~~~~~~~~~~~< Status Bar >~~~~~~~~~~~
status = Label(root, text = "Preparing to do nothing...", relief = SUNKEN, anchor = W)
status.grid(padx=5, pady=5, sticky = W)
root.mainloop()
I am trying to place my Entry() field above my main text filed
I think this is what you are looking for:
If so, then simply change:
keywordEntry.grid(row=3, column=1)
To:
keywordEntry.grid(row=1, column=0, sticky=W)
Nota Bene: This just resolves your problem, but there are other things to improve in your program.

Tkinter Grid Alignment Issue

I'm pretty new with tkinter and I can't figure why the q is not aligned near the Entry.
# String
self.user_p = StringVar()
self.user_q = StringVar()
self.user_r = StringVar()
self.user_result = StringVar()
# Label
self.description = Label(self.root, text="!p v (q ^ r)")
self.pLabel = Label(self.root, text="p")
self.qLabel = Label(self.root, text="q")
self.rLabel = Label(self.root, text="r")
self.resultLabel = Label(self.root, text="Result")
# Entry
self.p = Entry(self.root, textvariable = self.user_p, width = 10)
self.q = Entry(self.root, textvariable = self.user_q, width = 10)
self.r = Entry(self.root, textvariable = self.user_r, width = 10)
self.result = Entry(self.root, bg = "white", state=DISABLED, text = "")
# Grid
# Labels
self.description.grid(row = 0, column = 3, sticky = N)
self.pLabel.grid(row = 1, column = 0, sticky = E)
self.qLabel.grid(row = 1, column = 2, sticky = E)
self.rLabel.grid(row = 1, column = 4, sticky = E)
# Entry
self.p.grid(row=1, column=1)
self.q.grid(row = 1, column = 3)
self.r.grid(row=1, column=5)
(with or without the sticky it's still the same)
Here's a picture: http://imgur.com/a/wrOGa
The first part in the picture is what I'm getting right now. And the second part is what I want it to look like
Am I doing something wrong?
Welcome. I have taken the liberty to attach an example of a test code (see below). Please remember to do that in your post as mine can be different to yours. I did not encounter the issue you described. See attached picture. I am using python3.5 on Ubuntu 16.04.
One other thing, you can be more explicit by adding the option justify=RIGHT in your label widget commands to alight the label text to right.
from tkinter import *
class App(Frame):
def __init__(self, parent):
Frame.__init__(self, parent, background='pink')
# String
self.user_p = StringVar()
self.user_q = StringVar()
self.user_r = StringVar()
self.user_result = StringVar()
# Label
self.description = Label(self, text="!p v (q ^ r)")
self.pLabel = Label(self, text="p")
self.qLabel = Label(self, text="q")
self.rLabel = Label(self, text="r")
self.resultLabel = Label(self, text="Result")
# Entry
self.p=Entry(self, textvariable=self.user_p, width=10)
self.q=Entry(self, textvariable=self.user_q, width=10)
self.r=Entry(self, textvariable=self.user_r, width=10)
self.result=Entry(self, bg="white", state=DISABLED, text="")
# Grid
# Labels
self.description.grid(row=0, column=3, sticky=N)
self.pLabel.grid(row=1, column=0, sticky=E)
self.qLabel.grid(row=1, column=2, sticky=E)
self.rLabel.grid(row=1, column=4, sticky=E)
# Entry
self.p.grid(row=1, column=1)
self.q.grid(row=1, column=3)
self.r.grid(row=1, column=5)
if __name__ == '__main__':
root=Tk()
root.geometry("300x50")
app=App(root)
app.pack(fill="both", expand=True)
app.mainloop()

Categories

Resources