How to get variable value from Entry tkinter python? - python

I am trying to create a GUI with tkinter. I was able to setup the interface, with buttons, labels etc. However, when I type a string or int in the interface (using Entry, but also with combobox and chekcbutton) the assigned varible doesn't appear if try to print it, I only got printed the following instead of the variable values:
.!entry, .!entry2, .!combobox, .!checkbutton
Does anybody know how to fix it?
from tkinter import *
from tkinter.ttk import Combobox
from tkinter import filedialog
def browse_button1():
global folder_path
filename = filedialog.askdirectory()
folder_path1.set(filename)
def browse_button2():
global folder_path
filename = filedialog.askdirectory()
folder_path2.set(filename)
main_window = Tk()
folder_path1 = StringVar()
folder_path2 = StringVar()
var = StringVar()
def1 = StringVar(main_window, value='Sharp')
# Labels
Label(main_window, text= "Folder Path").grid(row = 0, column = 0)
Label(main_window, text= "Scan File").grid(row = 1, column = 0)
#Text Input
e1 = Entry(main_window, width= 50, borderwidth= 5, textvariable= folder_path1)
e1.grid(row= 0, column= 1, columnspan= 2, sticky="we", pady=10)
e2 = Entry(main_window, width= 50, borderwidth= 5, textvariable= folder_path2)
e2.grid(row= 1, column= 1, columnspan= 2, sticky="we", pady=10)
#Combobox list
var.set("Sharp")
data = ("Sharp", "Intermediate", "Standard", "Soft")
cb = Combobox(main_window, values=data, textvariable= def1)
cb.grid(row=4, column= 1, sticky = 'w', pady=10)
#Checkbutton
cbu = Checkbutton(main_window)
cbu.grid(row=6, column=1, sticky = 'w', pady=10)
def on_click():
print(f"{e1}, {e2}, {cb}, {cbu}")
#Buttons
Button(main_window, text= "Run", command = on_click, width = 25).grid(row= 8, column= 1, columnspan= 2, sticky="we", pady=10)
Button(main_window, text= "Browse", command = browse_button1, width = 12).grid(row= 0, column= 3)
Button(main_window, text= "Browse", command = browse_button2, width = 12).grid(row= 1, column= 3)
main_window.mainloop()

Use the .get() method to retrieve widget values. Simply change:
def on_click():
print(f"{e1}, {e2}, {cb}, {cbu}")
to:
# create a variable to store the Checkbutton state
cb_var = StringVar()
# update 'cbu' to use that variable
cbu = Checkbutton(main_window, variable=cb_var)
def on_click():
print(f"{e1.get()}, {e2.get()}, {cb.get()}, {cb_var.get()}")

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.

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()

Executable using tkinter and multiprocessing creates multiple windows

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.

Python Tkinter. Cant apply theme for second window of program

I am trying to make basic gui with Tkinter. But the default theme "Motif" is not pretty so I`ve switched to "Clam". But the problem in second window of my program, it still uses default theme "Motif".
Let me show at first my code:
from Tkinter import *
from ttk import *
def label(row, column, text):
L = Label(root, text=text, anchor='w')
L.grid(row=row,column=column,sticky="nw",pady=2,padx=3)
def button(root, row, column, text, command):
B = Button(root, text=text, command=command, width=15)
B.grid(row=row, column=column, sticky="e", pady=4, padx=3)
def entry(row, column, insert="", show=""):
E = Entry(root, width=32)
E.insert(0, insert)
E.config(show=show)
E.grid(row=row,column=column)
return E
def show_ldif():
values_list = []
givenname = var0.get()
sn = var1.get()
country = var2.get()
location = var3.get()
skype = var8.get()
cn = givenname[0].lower() + sn.lower()
email = cn + "#company.com"
# ldif is import format for openLDAP
ldif_list =[]
ldif_list.append(("dn: cn=%s,cn=people,ou=company,dc=company,dc=com\n") % cn)
ldif_list.append('c: %s\n'% country)
ldif_list.append('cn: %s\n'% cn)
ldif_list.append(('objectclass: inetOrgPerson\n'
'objectclass: posixAccount\n'
'objectclass: top\n'
'objectclass: shadowAccount\n'
'objectclass: ldapPublicKey\n'
'objectclass: extensibleObject\n'))
ldif = ''.join(ldif_list)
root2 = Tk()
root2.title("Result")
root2.style = Style()
root2.style.theme_use("clam")
ldif_text = Text(root2, height=30, width=50)
ldif_text.insert(END, ldif)
ldif_text.grid(row=0,column=0,columnspan = 2)
button(root2, 1, 1, "Copy to Clipboard", yes_no)
button(root2, 1, 0, "Import to LDAP", yes_no)
def yes_no():
pass
root = Tk()
root.style = Style()
root.style.theme_use("clam")
root.title("LDAP Adder")
label(0, 0, 'First name')
var0 = entry(0, 1)
label(1, 0, 'Second name')
var1 = entry(1, 1)
label(2, 0, 'Country (two letters)')
var2 = entry(2, 1)
label(3, 0, 'City')
var3 = entry(3, 1)
label(8, 0, 'Skype')
var8 = entry(8, 1)
label(13, 0, '')
button(root, 14, 0, 'Show', show_ldif)
button(root, 14, 1, 'Quit', root.quit)
root.mainloop()
First window looks well:
It is Calm theme for Tkinter. Then I can click on button 'Show' and second window 'Result' will appear:
But second one still uses default theme (look at buttons of right window). But why? I`ve activated "Calm" theme for second window:
root2 = Tk()
root2.title("Result")
root2.style = Style()
root2.style.theme_use("clam")
This is because you are creating two instances of Tk. That is not how tkinter is designed to be used. You must create exactly one instance of Tk. If you need additional windows, create instances of Toplevel.
With such code looks good:
from Tkinter import *
from ttk import *
def label(row, column, text):
L = Label(root, text=text, anchor='w')
L.grid(row=row,column=column,sticky="nw",pady=2,padx=3)
def button(root, row, column, text, command):
B = Button(root, text=text, command=command, width=15)
B.grid(row=row, column=column, sticky="e", pady=4, padx=3)
def entry(row, column, insert="", show=""):
E = Entry(root, width=32)
E.insert(0, insert)
E.config(show=show)
E.grid(row=row,column=column)
return E
def show_ldif():
values_list = []
givenname = var0.get()
sn = var1.get()
country = var2.get()
location = var3.get()
skype = var8.get()
cn = givenname[0].lower() + sn.lower()
email = cn + "#company.com"
# ldif is import format for openLDAP
ldif_list =[]
ldif_list.append(("dn: cn=%s,cn=people,ou=company,dc=company,dc=com\n") % cn)
ldif_list.append('c: %s\n'% country)
ldif_list.append('cn: %s\n'% cn)
ldif_list.append(('objectclass: inetOrgPerson\n'
'objectclass: posixAccount\n'
'objectclass: top\n'
'objectclass: shadowAccount\n'
'objectclass: ldapPublicKey\n'
'objectclass: extensibleObject\n'))
ldif = ''.join(ldif_list)
top = Toplevel()
top.title("Result")
ldif_text = Text(top, height=30, width=50)
ldif_text.insert(END, ldif)
ldif_text.grid(row=0,column=0,columnspan = 2)
button(top, 1, 1, "Copy to Clipboard", yes_no)
button(top, 1, 0, "Import to LDAP", yes_no)
def yes_no():
pass
root = Tk()
root.style = Style()
root.style.theme_use("clam")
root.title("LDAP Adder")
label(0, 0, 'First name')
var0 = entry(0, 1)
label(1, 0, 'Second name')
var1 = entry(1, 1)
label(2, 0, 'Country (two letters)')
var2 = entry(2, 1)
label(3, 0, 'City')
var3 = entry(3, 1)
label(8, 0, 'Skype')
var8 = entry(8, 1)
label(13, 0, '')
button(root, 14, 0, 'Show', show_ldif)
button(root, 14, 1, 'Quit', root.quit)
root.mainloop()
So before I have been creating new window with:
root2 = Tk()
root2.title("Result")
root2.style = Style()
root2.style.theme_use("clam")
And theme cant be applied. With #Rinzler help I changed this code to:
top = Toplevel()
top.title("Result")
And activated theme only once in the beginning.

Categories

Resources