I need to add a button that the user presses to launch a Tkinter.askdirectory, and be able to capture the result. I have tried many examples, but could not find anything that works successfully in my particular case (the case where I am new at this and don't really know what I am doing :)
I have commented out what I have done, so that the original code still works, and so you can sort of see what I have been trying. Which is mostly not working as I am in unfamiliar territory with Tk. Any help greatly appreciated.
#!/usr/bin/env python
import Tkinter
from Tkinter import *
import Tkinter, tkFileDialog
class Values(Tkinter.Tk):
"""docstring for Values"""
def __init__(self, parent):
Tkinter.Tk.__init__(self,parent)
self.parent = parent
self.initialize()
def initialize(self):
self.grid()
stepOne = Tkinter.LabelFrame(self, text=" Create A Playlist ")
stepOne.grid(row=0, columnspan=7, sticky='W',padx=5, pady=5, ipadx=5, ipady=5)
# self.getAdir = tkFileDialog.askdirectory(parent=stepOne, title='Please select a directory')
self.Val1Lbl = Tkinter.Label(stepOne,text="Playlist Name")
self.Val1Lbl.grid(row=0, column=0, sticky='E', padx=10, pady=2)
self.Val1Txt = Tkinter.Entry(stepOne)
self.Val1Txt.grid(row=0, column=1, columnspan=4, pady=2, sticky='WE')
self.Val2Lbl = Tkinter.Label(stepOne,text="Task")
self.Val2Lbl.grid(row=1, column=0, sticky='E', padx=10, pady=2)
self.Val2Var = StringVar()
self.Val2Txt = Tkinter.OptionMenu(stepOne, self.Val2Var, 'Layout','Anim Pass 1','Anim Pass 2', 'Lighting', 'Compositing')
self.Val2Txt.grid(row=1, column=1, columnspan=4, pady=2, sticky='WE')
self.Val3Lbl = Tkinter.Label(stepOne,text="Description")
self.Val3Lbl.grid(row=2, column=0, sticky='E', padx=10, pady=2)
self.Val3Txt = Tkinter.Entry(stepOne)
self.Val3Txt.grid(row=2, column=1, columnspan=4, pady=2, sticky='WE')
# self.Val4Lbl = Tkinter.Label(stepOne,text="Directory")
# self.Val4Lbl.grid(row=3, column=0, sticky='E', padx=10, pady=2)
# self.Val4Var = StringVar()
# self.Val4Var = Tkinter.Button(command=getAdir)
# self.Val4Txt.grid(row=3, column=1, columnspan=4, pady=2, sticky='WE')
self.val1 = None
self.val2 = None
self.val3 = None
# self.val4 = None
SubmitBtn = Tkinter.Button(stepOne, text="Submit",command=self.submit)
SubmitBtn.grid(row=4, column=3, sticky='W', padx=5, pady=2)
def submit(self):
self.val1=self.Val1Txt.get()
if self.val1=="":
Win2=Tkinter.Tk()
Win2.withdraw()
self.val2=self.Val2Var.get()
if self.val2=="":
Win2=Tkinter.Tk()
Win2.withdraw()
self.val3=self.Val3Txt.get()
if self.val3=="":
Win3=Tkinter.Tk()
Win3.withdraw()
# self.val4=self.Val4Var.get()
# if self.val4=="":
# Win4=Tkinter.Tk()
# Win4.withdraw()
self.quit()
if __name__ == '__main__':
app = Values(None)
app.title('Bulk Movie Upload')
app.mainloop() #this will run until it closes
#Print the stuff you want.
print app.val1,app.val2,app.val3 #,app.val4
Here is the revised code, from what I think you meant, but still has the errors in that it is not passing the variable out. I have edited this post, and the code, to simplify.
#!/usr/bin/env python
import Tkinter
from Tkinter import *
import Tkinter, tkFileDialog
class Values(Tkinter.Tk):
"""docstring for Values"""
def __init__(self, parent):
Tkinter.Tk.__init__(self,parent)
self.parent = parent
self.initialize()
def getAdir(self):
self.val5 = tkFileDialog.askdirectory(parent=self, title='Please select a directory')
def initialize(self):
self.grid()
stepOne = Tkinter.LabelFrame(self, text=" Create A Playlist ")
stepOne.grid(row=1, columnspan=8, sticky='W',padx=5, pady=5, ipadx=5, ipady=5)
self.Val5Lbl = Tkinter.Label(stepOne,text="Select Folder Containing Movies")
self.Val5Lbl.grid(row=4, column=0, sticky='E', padx=5, pady=2)
self.Val5Var = StringVar()
self.Val5Txt = Tkinter.Button(stepOne, text="Select Files", command=self.getAdir)
self.Val5Txt.grid(row=4, column=1, columnspan=4, pady=2, sticky='WE')
self.val5 = None
SubmitBtn = Tkinter.Button(stepOne, text="Submit",command=self.submit)
SubmitBtn.grid(row=6, column=3, sticky='W', padx=5, pady=2)
def submit(self):
self.val5=self.Val5Var.get()
if self.val5=="":
Win2=Tkinter.Tk()
Win2.withdraw()
self.quit()
if __name__ == '__main__':
app = Values(None)
app.title('Bulk Movie Upload')
app.mainloop() #this will run until it closes
#Print the stuff you want.
print "Folder is - " + app.val5
One big problem is that you are creating more than one instance of Tk. You can't do that. If you need more windows, create instances if Toplevel.
To call a function to ask for a directory, you need to create a function, and tie that function to a button. What you were doing was actually calling the function before you create the other widgets, rather than wait for the button press.
def getAdir(self):
self.val4 = tkFileDialog.askdirectory(parent=stepOne, title='Please select a directory')
...
self.Val4Var = Tkinter.Button(self, command=self.getAdir)
Note: after I wrote the above, the question was changed to include different code. Here are my comments on that code:
In the revised code, you're not doing what I suggested in my answer. You need to remove this line of code:
self.val5=self.Val5Var.get()
That is because self.val5 already contains the directory returned from askdirectory. It will be a string, not some sort of object with a get method.
You also continue to have the problem that you're opening more than one root window. That will cause additional problems.
Related
I am currently working on my Graphical User Interface for my program and I want to create an Entry widget in a menubar (in my case in the menubaroptions method) that shows an IntVar which is set to a certain number (in my case: 9) but is changeable by the user. In my Code i tried it with self.entrystring.get() but got the "self is not defined" error.
This is part of my code:
import tkinter
from tkinter.constants import *
from tkinter import messagebox
from struct import unpack
from codecs import decode
class Graphicaluserinterface(tkinter.Frame):
#classmethod
def main(cls):
root = tkinter.Tk()
root.title('Program')
root.minsize(560, 105)
gui = cls(root)
gui.grid(row=0, column=0, sticky=NSEW)
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
root['menu'] = gui.menubar
root.mainloop()
def __init__(self, master=None):
super().__init__(master)
self.inputliste = []
self.check1 = tkinter.IntVar()
self.check2 = tkinter.IntVar()
self.check3 = tkinter.IntVar()
self.check5 = tkinter.IntVar()
self.inputfilenamelist = []
self.fileopenname = tkinter.StringVar()
self.fileopenname1 = tkinter.StringVar()
self.filesavename =tkinter.StringVar()
self.entrystring = tkinter.IntVar()
self.taktzykluszeit = tkinter.DoubleVar()
self.taktunterschiedboolean = tkinter.BooleanVar()
self.fileopeningcounter = tkinter.IntVar()
self.fileopeningcounter.set(0)
self.menubar = tkinter.Menu(self)
self.file_menu = tkinter.Menu(self.menubar, tearoff=FALSE)
self.help_menu = tkinter.Menu(self.menubar, tearoff=FALSE)
self.program_start = tkinter.Button(self, text='Start Program')
self.check_button1 = tkinter.Checkbutton(
self, text="Drehzahl und Drehmoment", variable=self.check1,
onvalue=1, offvalue=0
)
self.check_button2 = tkinter.Checkbutton(
self, text="Analogvoltsensoren", variable=self.check2,
onvalue=1, offvalue=0
)
self.check_button3 = tkinter.Checkbutton(
self, text="Analogamperesensoren", variable=self.check3,
onvalue=1, offvalue=0
)
self.check_button4 = tkinter.Checkbutton(
self, text="Thermoelemente", variable=self.check4,
onvalue=1, offvalue=0
)
self.check_button5 = tkinter.Checkbutton(
self, text="Pt-100-Elemente", variable=self.check5,
onvalue=1, offvalue=0)
self.input_path_display = tkinter.Label(
self, textvariable=self.fileopenname1, bg='white', width=60
)
self.output_path_display = tkinter.Label(
self, textvariable=self.filesavename, bg="white", width=60
)
self.input_path_display_label = tkinter.Label(self, text="Inputfile")
self.output_path_display_label = tkinter.Label(self, text="Outputfile")
self.create_widgets()
self.entrystring.set(9)
self.taktzykluszeit.set(0.0)
self.taktunterschiedboolean.set(False)
def create_widgets(self):
self.menubar.add_cascade(label="File", menu=self.file_menu)
self.file_menu.add_command(label="Open", command=lambda:[self.inputfilenamelist.clear(),self.fileopening()])
self.file_menu.add_command(label="Save As")
self.file_menu.add_command(label="Options",command=self.menubaroptions)
self.file_menu.add_command(label="Exit", command=self.master.destroy)
self.menubar.add_cascade(label="Extras", menu=self.help_menu)
self.help_menu.add_command(label="Help")
self.help_menu.add_command(label="Credits")
pad = dict(padx=5, pady=5)
self.check_button1.grid(row=0, column=0, **pad)
self.check_button2.grid(row=1, column=0, **pad)
self.check_button3.grid(row=2, column=0, **pad)
self.check_button4.grid(row=3, column=0, **pad)
self.check_button5.grid(row=4, column=0, **pad)
self.input_path_display_label.grid(row=0, column=1, sticky=EW, **pad)
self.input_path_display.grid(row=1, column=1, sticky=NSEW, **pad)
self.output_path_display_label.grid(row=2, column=1, sticky=EW, **pad)
self.output_path_display.grid(row=3, column=1, sticky=NSEW, **pad)
self.program_start.grid(row=4, column=1, sticky=EW, **pad)
#self.program_start["command"]=lambda:[self.fileselectwarning(),self.writealldatafile(),self.writeselecteddata(),
# self.inputliste.clear(),self.fileopeningcounter.set(0),
# self.inputfilenamelist.clear()]
self.grid_rowconfigure(1, weight=1)
self.grid_columnconfigure(1, weight=1)
def menubaroptions(root):
optionswindow = tkinter.Toplevel(root)
optionswindow.title("Options")
optionswindow.minsize(300,150)
trennzeichenlabel = tkinter.Label(optionswindow,text="Length of Separator in Byte:").pack()
trennzeichenentry = tkinter.Entry(optionswindow,textvariable=self.entrystring.get(),width=30,justify="center").pack()
taktzykluszeitlabel = tkinter.Label(optionswindow,text="Measurementtime for all \n Temperature-Sensors in sec").pack()
taktzykluszeitentry = tkinter.Entry(optionswindow,textvariable=self.taktzykluszeit.get(),width=30,justify="center").pack()
if __name__ == '__main__':
Graphicaluserinterface.main()
i know there is a line which should be indented but it wasn´t working here, i have it indented in my code though.
There are a few issues:
In the function menubaroptions() you assign the textvariable to the IntVar.get() method when you should assign to the object:
trennzeichenentry = tkinter.Entry( ... textvariable=self.entrystring.get(), ...).pack()
should be:
trennzeichenentry = tkinter.Entry( ... textvariable=self.entrystring, ...).pack()
Then you define the function with the instance name root instead of self which means that self.entrystring will generate a NameError.
Then you try to create a Toplevel window as a child to root. But root is a local variable in the main() function and the menubaroptions() can't find it.
Now; you are using the decorator #classmethod and I'm not one with decorators yet, so I can't say if that affects the problem. But the things I mentioned above will get you part of the way.
When the application is run first, the last frame's widgets are displayed on the screen. What i wanted to do is, displaying the related frames when the user clicks their buttons. So, i want to display a blank frame with the top buttons. In order to do that, what should i do? (I removed the button functions, because they are not related to the question.) Thanks in advance.
import tkinter as tk
class TopFrame(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.grid(row=0, column=0, sticky="nsew")
self.BottomFrame = tk.Frame(master=master)
self.BottomFrame.grid(row=1, column=0, sticky="nsew")
self.f1 = tk.Frame(master=self.BottomFrame)
self.f2 = tk.Frame(master=self.BottomFrame)
self.f3 = tk.Frame(master=self.BottomFrame)
for f in (self.f1, self.f2, self.f3):
f.grid(row=0, column=0, sticky="nsew")
self.b1 = tk.Button(master=self, text="Add Words")
self.b2 = tk.Button(master=self, text="Add From File")
self.b3 = tk.Button(master=self, text="Change Words")
self.add_button = tk.Button(master=self.f1, text="Add")
self.open_button = tk.Button(master=self.f2, text="Open File")
self.change_button = tk.Button(master=self.f3, text="Change")
self.l1 = tk.Label(master=self.f1, text="English")
self.l2 = tk.Label(master=self.f1, text="Turkish")
self.l3 = tk.Label(master=self.f3, text="Old word")
self.l4 = tk.Label(master=self.f3, text="New word")
self.e1 = tk.Entry(master=self.f1)
self.e2 = tk.Entry(master=self.f1)
self.e3 = tk.Entry(master=self.f3)
self.e4 = tk.Entry(master=self.f3)
self.configure_buttons()
self.configure_labels()
self.configure_entries()
def configure_buttons(self):
self.b1.grid(row=0, column=0)
self.b1.configure(command=lambda: self.f1.tkraise())
self.b2.grid(row=0, column=1)
self.b2.configure(command=lambda: self.f2.tkraise())
self.b3.grid(row=0, column=2)
self.b3.configure(command=lambda: self.f3.tkraise())
self.add_button.grid(row=2, columnspan=2)
#self.add_button.configure(command=self.add_word)
self.open_button.pack(side="top")
#self.open_button.configure(command=self.add_from_file)
self.change_button.grid(row=2, columnspan=2)
def configure_labels(self):
self.l1.grid(row=0, column=0)
self.l2.grid(row=0, column=1)
self.l3.grid(row=0, column=0)
self.l4.grid(row=0, column=1)
def configure_entries(self):
self.e1.grid(row=1, column=0)
self.e2.grid(row=1, column=1)
self.e3.grid(row=1, column=0)
self.e4.grid(row=1, column=1)
if __name__ == "__main__":
root = tk.Tk()
example = TopFrame(master=root)
example.mainloop()
Instead of having 3 widgets in the same location, it's better to have only the one you need.
First, get rid of this code:
for f in (self.f1, self.f2, self.f3):
f.grid(row=0, column=0, sticky="nsew")
Now the frame will start in a blank state.
Then, instead of calling .tkraise() on the frames, we will remove the current frame (if any) and add another one in its place. So
self.b1.configure(command=lambda: self.f1.tkraise())
self.b2.configure(command=lambda: self.f2.tkraise())
self.b3.configure(command=lambda: self.f3.tkraise())
becomes:
self.b1.configure(command=lambda: self._activate(self.f1))
self.b2.configure(command=lambda: self._activate(self.f2))
self.b3.configure(command=lambda: self._activate(self.f3))
with
def _activate(self, frame):
# remove the current frame
for child in self.BottomFrame.winfo_children():
child.grid_forget()
# add the new frame in its place
frame.grid(row=0, column=0, sticky='nsew')
I'm new im Python, just started to learn about class and tkinter, so forgive me "messy" code.
I'm trying to enter some string to field nr1, and after click a button, print this string in console and store this value for later:
from tkinter import Tk, BOTH, RIGHT, RAISED, BOTTOM, TOP, X, StringVar
from tkinter.ttk import Frame, Button, Entry
class AD(Frame):
def __init__(self, parent):
Frame.__init__(self, parent, v=None, raw_input=None)
self.parent = parent
self.parent.geometry("250x150+300+300")
self.parent.title("Trolollo")
self.parent.resizable(False, False)
self.inp = None
self.v = StringVar()
self.raw_input = None
self.initUI()
def user_input(self):
global inp
a = self.raw_input(self.v.get())
inp = a
return inp
def initUI(self):
self.pack(fill=BOTH, expand=True)
frame = Frame(self, relief=RAISED, borderwidth=0)
frame.pack(fill=BOTH, expand=True)
self.entry1 = Entry(frame, textvariable=self.v)
self.entry1.pack(side=TOP, fill=X, expand=False, padx=2, pady=2)
self.entry1.focus_set()
rename_button = Button(frame, text="Dispaly text", command = self.user_input())
rename_button.pack(side=TOP, expand=False, padx=2, pady=2)
entry2 = Entry(frame)
entry2.pack(side=TOP, fill=X, expand=False, padx=2, pady=2)
quit_button = Button(self, text="Quit", command=self.quit)
quit_button.pack(side=RIGHT, padx=5, pady=5)
ok_button = Button(self, text="OK")
ok_button.pack(side=RIGHT, padx=5, pady=5)
def main():
root = Tk()
app = AD(root)
root.mainloop()
if __name__ == '__main__':
main()
After executing code, i get:
TypeError: 'NoneType' object is not callable
Any help would me appreciated
ISSUES:
First issue laid in your rename_button's option "command=self.user_input()". You were suppose to name the function
and not execute the function. Putting the () symbol meant you
executed the function when your code loaded, i.e. it executed once
w/o pressing the rename button.
Second issue was the erroneous code in your function user_input. This caused your error msg.
ANSWER: Code with the suggested corrections.
from tkinter import *
from tkinter.ttk import *
class AD(Frame):
def __init__(self, parent):
Frame.__init__(self, parent, v=None, raw_input=None)
self.parent = parent
self.parent.geometry("250x150+300+300")
self.parent.title("Trolollo")
self.parent.resizable(False, False)
self.inp = None
self.v = StringVar()
self.raw_input = None
self.initUI()
def user_input(self):
# Get entry1 value, store it as an attribute and print to console
self.raw_input = self.v.get()
print(self.raw_input)
def initUI(self):
self.frame = Frame(self, relief=RAISED, borderwidth=0)
self.frame.pack(fill=BOTH, expand=True)
self.entry1 = Entry(self.frame, textvariable=self.v)
self.entry1.pack(side=TOP, fill=X, expand=False, padx=2, pady=2)
self.entry1.focus_set()
#self.rename_button = Button(self.frame, text="Dispaly text",
# command = self.user_input())
self.rename_button = Button(self.frame, text="Display text",
command = self.user_input)
self.rename_button.pack(side=TOP, expand=False, padx=2, pady=2)
# You can remove the triple quotes to display these widgets
"""
self.entry2 = Entry(self.frame)
self.entry2.pack(side=TOP, fill=X, expand=False, padx=2, pady=2)
self.quit_button = Button(self.frame, text="Quit", command=self.quit)
self.quit_button.pack(side=RIGHT, padx=5, pady=5)
self.ok_button = Button(self.frame, text="OK")
self.ok_button.pack(side=RIGHT, padx=5, pady=5)
"""
self.pack(fill=BOTH, expand=True)
def main():
root = Tk()
app = AD(root)
root.mainloop()
Your GUI :
SUGGESTIONS:
Do remember to put self. in front of your widgets.
Do test one widget at a time to help you debug your code.
I'm having issues with my constructor. I get the error __init__() missing 1 required positional argument: 'checkbutton'
Update:
this is my main file:
from GUI_Rootmodule import GUI_Root
gui_root = GUI_Root()
this is my rootmodule file:
from GUI_Unitmodule import Unit
from tkinter import *
class GUI_Root:
def __init__(self):
print("hoi")
window = Tk()
window.title("Project: Embedded Systems")
rootframe = Frame(window, width=1800, height=750)
rootframe.pack()
Unit(rootframe)
window.mainloop()
this is my Unitmodule:
from tkinter import *
class Unit:
def __init__(self, master, checkbutton):
self.frame1 = Frame(master) #Frame voor labels, buttons, entries
self.frame1.pack()
# Checkbutton #
print("test frame")
self.var1 = IntVar()
self.checkbutton = checkbutton(self.frame1, text="Automatisch", variable=self.var1, onvalue= 1, offvalue= 0, pady=20).grid(row=0, column=0, sticky=E)
print("test checkbutton")
# Labels #
self.Extend_Label = Label(self.frame1, text="Uitrol afstand", pady=20).grid(row=2, column=0, sticky=E)
self.Retract_Label = Label(self.frame1, text="Inrol afstand", pady=20).grid(row=3, column=0, sticky=E)
self.Temperture_Label = Label(self.frame1, text="Temperatuur Trigger", pady=20).grid(row=4, column=0, sticky=E)
self.LightIntensity_Label = Label(self.frame1, text="Lichtintensiteit Trigger", pady=20).grid(row=5, column=0, sticky=E)
print("test label")
# Entry #
self.Extend_Entry = Entry(self.frame1).grid(row=2, column=1, sticky=E)
self.Retract_Entry = Entry(self.frame1).grid(row=3, column=1, sticky=E)
self.Temperture_Entry = Entry(self.frame1).grid(row=4, column=1, sticky=E)
self.LightIntensity_Entry = Entry(self.frame1).grid(row=5, column=1, sticky=E)
print("test entry")
# Buttons
self.A = Button(self.frame1, text ="Inrollen", padx=10, pady=20).grid(row=6, column=0)
self.B = Button(self.frame1, text ="Uitrollen", padx=10, pady=20).grid(row=6, column=1)
print("test button")
I've tried to run in it, but it keeps saying that I'm missing an argument which i've put in init(self, master, checkbutton)
Can someone explain what I'm missing here and/or doing wrong ?
Update 2: Without the checkbutton code, the rest works and shows a simple GUI. It's still not clear where exactly i'm missing the argument for checkbutton
You didn't supply all of the required input parameters on this line:
Unit(rootframe)
You supplied master, but are missing checkbutton. The class should be instantiated with all of the required input parameters:
Unit(master, checkbutton)
Alternatively, you can provide default values for the inputs and adjust the code in the function accordingly:
class Unit(master=None,checkbutton=None):
...
However, it looks like maybe you don't intend to pass in a checkbutton variable at all and meant to simply include a tkinter Checkbutton. If that's what you're after, I've included code for that below. I avoided the star import from tkinter import * so the source of the objects is more clear. I also combined things into the same module so the whole thing runs as-is.
import tkinter as tk
def main():
gui_root = GUI_Root()
class GUI_Root:
def __init__(self):
print("hoi")
window = tk.Tk()
window.title("Project: Embedded Systems")
rootframe = tk.Frame(window, width=1800, height=750)
rootframe.pack()
Unit(rootframe)
window.mainloop()
class Unit:
def __init__(self, master):
self.frame1 = tk.Frame(master) #Frame voor labels, buttons, entries
self.frame1.pack()
# Checkbutton #
print("test frame")
self.var1 = tk.IntVar()
self.checkbutton = tk.Checkbutton(self.frame1, text="Automatisch", variable=self.var1, onvalue= 1, offvalue= 0, pady=20).grid(row=0, column=0, sticky=tk.E)
print("test checkbutton")
# Labels #
self.Extend_Label = tk.Label(self.frame1, text="Uitrol afstand", pady=20).grid(row=2, column=0, sticky=tk.E)
self.Retract_Label = tk.Label(self.frame1, text="Inrol afstand", pady=20).grid(row=3, column=0, sticky=tk.E)
self.Temperture_Label = tk.Label(self.frame1, text="Temperatuur Trigger", pady=20).grid(row=4, column=0, sticky=tk.E)
self.LightIntensity_Label = tk.Label(self.frame1, text="Lichtintensiteit Trigger", pady=20).grid(row=5, column=0, sticky=tk.E)
print("test label")
# Entry #
self.Extend_Entry = tk.Entry(self.frame1).grid(row=2, column=1, sticky=tk.E)
self.Retract_Entry = tk.Entry(self.frame1).grid(row=3, column=1, sticky=tk.E)
self.Temperture_Entry = tk.Entry(self.frame1).grid(row=4, column=1, sticky=tk.E)
self.LightIntensity_Entry = tk.Entry(self.frame1).grid(row=5, column=1, sticky=tk.E)
print("test entry")
# Buttons
self.A = tk.Button(self.frame1, text ="Inrollen", padx=10, pady=20).grid(row=6, column=0)
self.B = tk.Button(self.frame1, text ="Uitrollen", padx=10, pady=20).grid(row=6, column=1)
print("test button")
if __name__ == '__main__':
main()
I have the following GUI code, that I cant't get to work. I want it do the following:
For the submit function, I want it to check if the Val1 or Val2 are blank and then warn the user and pause the function to allow the user to enter a value and then carryout the rest of the function. This includes closing the GUI (which I don't know how to do, except closing it manually).
I also want the GUI to return Val1 and Val2 out of the class. The last line of the code is "print Total", which is the name I have given to the returned values.
import Tkinter
import tkMessageBox
class Values(Tkinter.Tk):
def __init__(self,parent):
Tkinter.Tk.__init__(self,parent)
self.parent = parent
self.initialize()
def initialize(self):
self.grid()
stepOne = Tkinter.LabelFrame(self, text=" 1. Enter Values ")
stepOne.grid(row=0, columnspan=7, sticky='W',padx=5, pady=5, ipadx=5, ipady=5)
Val1Lbl = Tkinter.Label(stepOne,text="Value 1")
Val1Lbl.grid(row=0, column=0, sticky='E', padx=5, pady=2)
Val1Txt = Tkinter.Entry(stepOne)
Val1Txt.grid(row=0, column=1, columnspan=3, pady=2, sticky='WE')
Val2Lbl = Tkinter.Label(stepOne,text="Value 2")
Val2Lbl.grid(row=1, column=0, sticky='E', padx=5, pady=2)
Val2Txt = Tkinter.Entry(stepOne)
Val2Txt.grid(row=1, column=1, columnspan=3, pady=2, sticky='WE')
def submit():
Val1=Val1Txt.get()
if Val1 == '':
Win2=Tkinter.Tk()
Win2.withdraw()
tkMessageBox.showinfo(message="Value 1 is empty")
##Stop submit from going any further.Allow user to enter a value and then
##carryout.
Val2=Val2Txt.get()
if Val2 == '':
Win2=Tkinter.Tk()
Win2.withdraw()
tkMessageBox.showinfo(message="Value 2 is empty")
###Stop submit from going any further.Allow user to enter a value and then
##carryout
###Close GUI (Part of submit function)
return Val1,Val2
SubmitBtn = Tkinter.Button(stepOne, text="Submit",command=submit)
SubmitBtn.grid(row=4, column=3, sticky='W', padx=5, pady=2)
if__name__== "__main__":
app = Values(None)
app.title('Values')
app.mainloop()
###Do something with returned values
Total = Values##Is this the correct way of getting the returned values?
print Total
Hrrm... are you sure you don't want to just have Val1 and Val2 be attributes of the Values class, and have the submit button set the values?
Then you can check/return/use them whenever you want with self.Val1 and self.Val2? Also you can destroy the window with self.destroy() or self.quit() (look each of these methods up and determine which is useful to you).
In general, button callbacks are not used to return values in the way that you are describing. Typically they will run some function that does some processing or modifying of the class's attributes.
Also, remember, these attributes can be accessed after exiting the mainloop, which appears to be the sort of thing that you are wanting to do with them:
Edit: Below is a slightly simplified version of your code. I removed the message box stuff, made the values and the fields attributes of your class, and added a quit() method in your submit button.
import Tkinter
class Values(Tkinter.Tk):
"""docstring for Values"""
def __init__(self, parent):
Tkinter.Tk.__init__(self,parent)
self.parent = parent
self.initialize()
def initialize(self):
self.grid()
stepOne = Tkinter.LabelFrame(self, text=" 1. Enter Values ")
stepOne.grid(row=0, columnspan=7, sticky='W',padx=5, pady=5, ipadx=5, ipady=5)
self.Val1Lbl = Tkinter.Label(stepOne,text="Value 1")
self.Val1Lbl.grid(row=0, column=0, sticky='E', padx=5, pady=2)
self.Val1Txt = Tkinter.Entry(stepOne)
self.Val1Txt.grid(row=0, column=1, columnspan=3, pady=2, sticky='WE')
self.Val2Lbl = Tkinter.Label(stepOne,text="Value 2")
self.Val2Lbl.grid(row=1, column=0, sticky='E', padx=5, pady=2)
self.Val2Txt = Tkinter.Entry(stepOne)
self.Val2Txt.grid(row=1, column=1, columnspan=3, pady=2, sticky='WE')
self.val1 = None
self.val2 = None
SubmitBtn = Tkinter.Button(stepOne, text="Submit",command=self.submit)
SubmitBtn.grid(row=4, column=3, sticky='W', padx=5, pady=2)
def submit(self):
self.val1=self.Val1Txt.get()
if self.val1=="":
Win2=Tkinter.Tk()
Win2.withdraw()
self.val2=self.Val2Txt.get()
if self.val2=="":
Win2=Tkinter.Tk()
Win2.withdraw()
self.quit()
if __name__ == '__main__':
app = Values(None)
app.title('Values')
app.mainloop() #this will run until it closes
#Print the stuff you want.
print app.val1,app.val2