The problem I am having is that the function below works fine on the first pass with regards to displaying the chosen value at the top of the OptionMenu before the 'Enter' button is clicked:
First pass
However on a second pass and any future passes to the function the chosen value is not displayed at the top of the OptionMenu (although if selected it will be used) before the 'Enter' Button is pressed:
Second etc. passes
The code is:
def load_create_list(self):
self.app = Toplevel(self.parent)
self.parent.withdraw()
self.app.title("Rgs2")
self.student = []
self.student1=[]
self.gs1=0
self.ng1=0
options = ["2", "3", "4", "5", "6", "7"]
self.results=[]
self.ngg=StringVar() #for the option menu widget the variable must be a stringVar not a normal string, int etc.
self.ng = Label(self.app, text="Number of groups")
self.ng.grid(row=2, column=0)
self.ngg.set("3")
self.ng1 = OptionMenu(self.app, self.ngg, *options)
self.ng1.grid(row=2, column=1, ipadx=10)
for i in range(0,len(self.x3)):
self.L1 = Label(self.app,text="Student")
self.L1.grid(row=i+4, column=0)
self.en = Entry(self.app)
self.en.insert(END, self.x3[i])
self.en.grid(row=i+4, column=1)
self.student.append(self.en)
self.el = int(len(self.student)+1)
for h in range(self.el,self.el+5):
self.L2 = Label(self.app,text="Student")
self.L2.grid(row=h+4, column=0)
self.em = Entry(self.app)
self.em.grid(row=h+4, column=1)
self.student.append(self.em)
button=Button(self.app,text="enter",command=lambda : self.hallo2()).grid(row=h+7,column=0)
button=Button(self.app,text="Save List",command=lambda : self.save_list2()).grid(row=h+7,column=1)
I have tried everything but can't understand what might be causing this issues. Any help would be gladly appreciated. Seems like very odd behaviour could it be something outside of the function that is causing the issue?
Full code is:
from Tkinter import *
from tkFileDialog import askopenfile
class main_menu:
def __init__(self, parent):
self.myParent = parent
self.myContainer1 = Frame(parent)
parent.title("Random Group Sorter")
self.myContainer1.pack()
self.button1 = Button(self.myContainer1, command = lambda : self.hope())
self.button1.configure(text="Create List", height = 1, width = 20, font=("Arial", 16))
self.button1.pack(side=TOP)
self.button1.focus_force()
self.button3 = Button(self.myContainer1, command = lambda : self.hope1())
self.button3.configure(text="Load List", height = 1, width = 20, font=("Arial", 16))
self.button3.pack(side=TOP)
self.button2 = Button(self.myContainer1, command = lambda : exit(), )
self.button2.configure(text="Exit",height = 1, width = 20, font=("Arial", 16))
self.button2.pack(side=TOP)
def hope(self):
self.myParent.destroy()
create_list()
def hope1(self):
self.myParent.destroy()
load_list()
class create_list():
def __init__(self):
parent = Tk()
self.parent=parent
self.student = []
self.student1 =[]
self.student2 =[]
self.fake_student = []
self.results=[]
self.ngg = StringVar()# for the option menu widget the variable must be a stringVar not a normal string, int etc.
self.ng = Label(text="Number of groups")
self.ng.grid(row=2, column=0)
self.ng = OptionMenu(parent, self.ngg, "2", "3", "4", "5","6")
self.ng.grid(row=2, column=1)
for i in range(3,21):
self.L1 = Label(text="Student")
self.L1.grid(sticky=E)
self.en = Entry(parent)
self.en.grid(row=i, column=1)
self.student.append(self.en)
button=Button(parent,text="Enter",command=lambda : self.hallo()).grid(row=23,column=0)
button=Button(parent,text="Save List",command=lambda : self.save_list()).grid(row=23,column=1)
parent.mainloop()
def hallo(self):
self.gs1 = int(len(self.student))
self.ng1 = int(self.ngg.get())# still need to use .get even though a stringvar
for entry in self.student:
self.student1.append(entry.get())
self.student1 = filter(None, self.student1)
for i in self.student1:# this is added as there are duplicate entries in the student list if saved
if i not in self.student2:
self.student2.append(i)
self.parent.destroy()
lis_an(self.student2,self.ng1)
def save_list(self):
for entry in self.student:
self.student1.append(entry.get())
self.student1 = filter(None, self.student1)
import tkFileDialog
root = Tk()
root.withdraw()
file_name = tkFileDialog.asksaveasfile(parent=root)
root.destroy()
print >>file_name, "\n"
print >>file_name, "\n".join(self.student1)
file_name.close()
class load_list:
def __init__(self):
self.x = []
self.x3 = []
self.load_clean()
self.root = Tk()
def load_clean(self):#option to load an already created file, cleans unwanted info from the list
import tkFileDialog
root = Tk()
root.withdraw()
file_name = tkFileDialog.askopenfile(parent=root)
root.destroy()
self.x = file_name.readlines()
file_name.close()
x2 =self.x[:]
for z in self.x:
if z [0:6]== "Random" or z == '\n' or z[0:5] == "Group":
x2.remove(z)
for c in range (0,len(x2)):
v = x2[c].rstrip()# this strip spaces and \n from each list item and returns the cleaned up string
self.x3.append(v)
self.load_create_list()
def load_create_list(self):
parent = Tk()
self.parent=parent
self.student = []
self.student1=[]
self.gs1=0
self.ng1=0
self.results=[]
self.ngg = StringVar()# for the option menu widget the variable must be a stringVar not a normal string, int etc.
self.ng = Label(text="Number of groups")
self.ng.grid(row=2, column=0)
self.ng = OptionMenu(parent, self.ngg, "2", "3", "4", "5", "6")
self.ng.grid(row=2, column=1)
for i in range(0,len(self.x3)):
self.L1 = Label(text="Student")
self.L1.grid(row=i+3, column=0)
self.en = Entry(parent)
self.en.insert(END, self.x3[i])
self.en.grid(row=i+3, column=1)
self.student.append(self.en)
self.el = int(len(self.student)+1)
for h in range(self.el,self.el+5):
self.L2 = Label(text="Student")
self.L2.grid(row=h+3, column=0)
self.em = Entry(parent)
self.em.grid(row=h+3, column=1)
self.student.append(self.em)
button=Button(parent,text="enter",command=lambda : self.hallo2()).grid(row=h+6,column=0)
button=Button(parent,text="Save List",command=lambda : self.save_list2()).grid(row=h+6,column=1)
parent.mainloop()
def hallo2(self):
self.student2= []
self.gs1 = int(len(self.student))
self.ng1 = int(self.ngg.get())# still need to use .get even though a stringvar
for entry in self.student:
self.student1.append(entry.get())
self.student1 = filter(None, self.student1)
for i in self.student1:# this is added as there are duplicate entries in the student list if saved
if i not in self.student2:
self.student2.append(i)
self.parent.destroy()
lis_an(self.student2,self.ng1)
def save_list2(self):
for entry in self.student:
self.student1.append(entry.get())
self.student1 = filter(None, self.student1)
import tkFileDialog
root = Tk()
root.withdraw()
file_name = tkFileDialog.asksaveasfile(parent=root)
root.destroy()
print >>file_name, "\n"
print >>file_name, "\n".join(self.student1)
file_name.close()
class lis_an:
def __init__(self,student1,ng1):
self.student1 = student1
self.ng1=ng1
self.results = []
self.randomList()
def randomList(self): # this creates a random list of students on the course
import random
studentb = self.student1[:]# this is added as otherwise the student list is overwritten
studentc = []
for i in range(len(studentb)):
element = random.choice(studentb)
studentb.remove(element)
studentc.append(element)
self.student1 = studentc
self.partition()
def partition(self): # this creates sub list of the student list containing the groups of students
increment = len(self.student1) / float(self.ng1)
last = 0
i = 1
while last < len(self.student1):
idx = int(round(increment * i))
self.results.append(self.student1[last:idx])
last = idx
i += 1
output(self.results, self.ng1)
class output:
def __init__(self, student, ng1):
self.ng1 = ng1
self.student = student
self.parent = Tk()
for item1 in range (0,len(self.student)):
test1 = "Group " + str(item1+1)+ ":"
v = Label(self.parent, text=test1, font=("Arial", 13))
test = "\n".join(self.student[item1])
w = Label(self.parent, text=test, justify = LEFT, font=("Arial", 12))
v.pack(side="top", anchor="w")
w.pack(side="top", anchor="w")
button=Button(self.parent,text="Repeat",command=lambda : self.join_list()).pack(side="top", anchor="w")
button=Button(self.parent,text="Main Menu",command=lambda : self.menu_link()).pack(side="top", anchor="w")
mainloop()
def join_list(self):#this function creates a new undivided version of student to feed back to lis_an
self.parent.destroy()
self.student = [j for i in self.student for j in i]
lis_an(self.student,self.ng1)
def menu_link(self):#destroys the parent frame and returns back to main menu
self.parent.destroy()
main()
def main():
parent = Tk()
myapp = main_menu(parent)
parent.mainloop()
main()
Very Simple solution to this problem. I was not defining self.ngg as a StringVar in the parent widget so:
self.ngg = StringVar()
Would cause the error, and
self.ngg = StringVar(self.app)
Solves the problem. Not quite sure why this would occur on the second and subsequent uses of the function but not the first.
Related
My code:
import tkinter
class latinwords:
def __init__(self):
self.main = tkinter.Tk()
self.top = tkinter.Frame(self.main)
self.mid = tkinter.Frame(self.main)
self.latinword1 = tkinter.Button(self.mid, text = 'sinister', command = self.cbfunction)
self.latinword2 = tkinter.Button(self.mid, text = 'dexter', command = self.cbfunction2)
self.latinword3 = tkinter.Button(self.mid, text = 'medium', command = self.cbfunction3)
self.toplabel = tkinter.Label(self.top, text= 'Latin')
self.toplabel2 = tkinter.Label(self.top, text= '\tEnglish')
self.value = tkinter.StringVar()
self.value1 = tkinter.StringVar()
self.value2 = tkinter.StringVar()
self.labels = tkinter.Label(self.bot, textvariable = self.value)
self.labels1 = tkinter.Label(self.bot, textvariable = self.value1)
self.labels2 = tkinter.Label(self.bot, textvariable = self.value2)
self.labels.pack()
self.labels1.pack()
self.labels2.pack()
self.top.pack()
self.mid.pack()
self.latinword1.pack()
self.latinword2.pack()
self.latinword3.pack()
self.toplabel.pack(side='left')
self.toplabel2.pack(side='left')
tkinter.mainloop()
def cbfunction(self):
value = 'left'
self.value1.set(value)
def cbfunction2(self):
value = 'right'
self.value.set(value)
def cbfunction3(self):
value = 'centre'
self.value2.set(value)
s = latinwords()
Unexpected output:
Expected output:
As you can see, I am trying to get my expected output with 3 buttons that can show the English word after its being pressed. But I got my output vertically with my own code. I am expecting my button and the matched word are on same horizontal level. Can anyone help me with this issue? Thanks.
It is better to put all the labels and buttons in same frame and use grid() instead of pack():
import tkinter
class latinwords:
def __init__(self):
self.main = tkinter.Tk()
self.mid = tkinter.Frame(self.main)
self.mid.pack()
self.latinword1 = tkinter.Button(self.mid, text='sinister', command=self.cbfunction)
self.latinword2 = tkinter.Button(self.mid, text='dexter', command=self.cbfunction2)
self.latinword3 = tkinter.Button(self.mid, text='medium', command=self.cbfunction3)
self.toplabel = tkinter.Label(self.mid, text='Latin')
self.toplabel2 = tkinter.Label(self.mid, text='English')
self.value = tkinter.StringVar()
self.value1 = tkinter.StringVar()
self.value2 = tkinter.StringVar()
self.labels = tkinter.Label(self.mid, textvariable=self.value)
self.labels1 = tkinter.Label(self.mid, textvariable=self.value1)
self.labels2 = tkinter.Label(self.mid, textvariable=self.value2)
self.labels.grid(row=1, column=1)
self.labels1.grid(row=2, column=1)
self.labels2.grid(row=3, column=1)
self.latinword1.grid(row=1, column=0)
self.latinword2.grid(row=2, column=0)
self.latinword3.grid(row=3, column=0)
self.toplabel.grid(row=0, column=0)
self.toplabel2.grid(row=0, column=1)
tkinter.mainloop()
def cbfunction(self):
value = 'left'
self.value.set(value)
def cbfunction2(self):
value = 'right'
self.value1.set(value)
def cbfunction3(self):
value = 'centre'
self.value2.set(value)
s = latinwords()
Solution:
The self.bot attribute is missing.
self.bot = tkinter.Frame(self.main)
You should set the position of packing of frames.
self.top.pack(side=tkinter.TOP)
self.mid.pack(side=tkinter.LEFT)
self.bot.pack(side=tkinter.RIGHT)
Test/Output:
>>> python3 test.py
NOTE:
The order of English words are not correct but it is not related to question.
I recommend to use the grid instead of pack. You can make more nice GUI with grid in your case. See more: https://tkdocs.com/tutorial/grid.html
I can't seem to update my money counter(var money) when its labeled, I have a button that's supposed to add 0.1 to moneyNum but the money counter doesn't change. I'm new to stack overflow and would appreciate any help.(btw sry if its REALLY messy)
from tkinter import *
import random
from time import sleep
root = Tk()
root.geometry('320x320')
#spacing
spacingTitle = Label(root, text=" \n\n\n\n\n\n\n\n\n")
#title
title = Label(root, text=" \bGamblers Dream\b", font="Helvetica", fg="red")
titleWelcom = Label(root, text=" Welcom to...")
titleWelcom.grid()
title.grid()
#money counter
moneyNum = float(10.0)
money = Label(root, text="money:" + str(moneyNum), font="Helvetica")
money.grid(row=3, column=0)
#moneyClicker
def moneyButtonAdder():
global moneyNum
moneyNum = moneyNum + 0.1
moneyClicker = Button(root, text="click", fg="green", command=moneyButtonAdder)
moneyClicker.grid(row=14)
root.mainloop()
The problem is that once you create a label, you pass the string to it. Label displays the string, and:
changing a string object does not change the label text
changing the integer does not change the string - it lost the whole connection when the new string object was created
So everything is not as procedural as you would have hoped it is.
The solution - use StringVar objects and detect value changes - see this.
So, the solution is:
from tkinter import *
class Observed(object):
"""adapted copy from https://stackoverflow.com/a/6192298/10713244"""
def __init__(self):
self._observed = 10.0
self._observers = []
#property
def observed(self):
return self._observed
#observed.setter
def observed(self, value):
self._observed = value
for callback in self._observers:
print('announcing change')
callback(self._observed)
def bind_to(self, callback):
print('bound')
self._observers.append(callback)
class Observer(object):
def __init__(self, data):
self.text = ''
self.data = data
self.data.bind_to(self.update)
self.tkinter_init()
def update(self, observed):
self.text = 'float: '+str(data._observed)
self.tkinter_update()
def tkinter_init(self):
self.tk = Tk()
self.tvar = StringVar()
self.label = Label(textvariable=self.tvar)
self.label.pack()
def tkinter_update(self):
self.tvar.set(self.text)
if __name__ == '__main__':
data = Observed()
label = Observer(data)
print(label.text)
data.observed = 10.0
print(label.text)
def dec(): data.observed -= 0.1
Button(label.tk, text='decrease', command=dec).pack()
label.tk.mainloop()
Hope that's helpful!
I'm trying to avoid to multiply functions in code by using
def Return_Label(self,number)
with a parameter.
Any Idea how to use string in order to define variable name usable to .set value to StringVar()?
Example code below:
import tkinter as tk
from tkinter import *
class WINDOW():
def __init__(self):
self.Settings_Window()
def Settings_Window(self):
self.settings_window = tk.Tk()
self.settings_window.minsize(200,200)
self.entry = Entry(self.settings_window)
self.entry.pack()
self.entry2 = Entry(self.settings_window)
self.entry2.pack()
self.label1input = StringVar()
self.label = Label(self.settings_window,textvariable=self.label1input, bg='yellow')
self.label.pack(expand='yes',fill='x')
self.label2input = StringVar()
self.label2 = Label(self.settings_window, textvariable=self.label2input, bg='yellow')
self.label2.pack(expand='yes', fill='x')
self.button = Button(self.settings_window,text='SETUP1',command=self.Next)
self.button.pack()
self.button2 = Button(self.settings_window,text='SETUP2',command=self.Next2)
self.button2.pack()
self.settings_window.mainloop()
def Next(self):
self.number=1
self.Return_Label(self.number)
def Next2(self):
self.number=2
self.Return_Label(self.number)
def Return_Label(self,number):
self.entry_field_value = self.entry.get()
print(self.entry_field_value)
#self.label1input.set(self.entry_field_value)
setattr(self,'label'+str(number)+'input.set',self.entry_field_value)
window=WINDOW()
I prefer a list approach to managing multiple entry fields and updating values.
By using list you can use the index value to manage the labels as well :D.
See the below example of how you can use list to deal with all the values and updates.
import tkinter as tk
from tkinter import *
class Window(tk.Tk):
def __init__(self):
super().__init__()
self.minsize(200, 200)
self.entry_list = []
self.label_list = []
entry_count = 2
for i in range(entry_count):
self.entry_list.append(Entry(self))
self.entry_list[i].pack()
for i in range(entry_count):
self.label_list.append(Label(self,bg='yellow'))
self.label_list[i].pack(expand='yes', fill='x')
Button(self, text='SETUP', command=self.Return_Label).pack()
def Return_Label(self):
for ndex, lbl in enumerate(self.label_list):
lbl.config(text=self.entry_list[ndex].get())
if __name__ == '__main__':
Window().mainloop()
Create lists of objects rather than individual attributes for each object. For example,
import tkinter as tk
from tkinter import *
class Window:
def __init__(self):
self.settings_window()
def Settings_Window(self):
self.settings_window = tk.Tk()
self.settings_window.minsize(200,200)
self.entries = [
Entry(self.settings_window),
Entry(self.settings_window)
]
for e in self.entries:
e.pack()
self.labelinputs = [
StringVar(),
StringVar()
]
self.labels = [
Label(self.settings_window, textvariable=label, bg='yellow')
for label in self.labelinputs
]
for l in self.labels:
l.pack(expand='yes', fill='x')
self.buttons = [
Button(self.settings_window,text='SETUP1',command=lambda: self.return_label(0))
Button(self.settings_window,text='SETUP2',command=lambda: self.return_label(1))
]
for b in self.buttons:
b.pack()
self.settings_window.mainloop()
def return_label(self,number):
entry_field_value = self.entry.get()
self.labelsinput[number].set(entry_field_value)
window=WINDOW()
Dynamicly computing variable names should be avoided at all costs. They are difficult to do correctly, and it makes your code hard to understand, hard to maintain, and hard to debug.
Instead, store the widgets in a dictionary or list. For example:
def __init___(self):
...
self.vars = {}
...
self.vars[1] = StringVar()
self.vars[2] = StringVar()
...
def Return_Label(self,number):
self.entry_field_value = self.entry.get()
var = self.vars[number]
var.set(self.entry_field_value)
Though, you really don't need to use StringVar at all -- they usually just add extra overhead without providing any extra value. You can save the labels instead of the variables, and call configure on the labels
self.labels[1] = Label(...)
...
self.labels[number].configure(text=self.entry_field_value)
I am creating a simple GUI program to manage priorities. I am having troubles with adding items to the listbox. I tried to create an instance of Priority class by passing two attributes to the constructor and then use g.listBox.insert(END, item), but it seems it doesn't work like that. I am getting an error:
/usr/bin/python3.5 /home/cali/PycharmProjects/priorities/priorities.py
Exception in Tkinter callback Traceback (most recent call last):
File "/usr/lib/python3.5/tkinter/init.py", line 1553, in call
return self.func(*args) File "/home/cali/PycharmProjects/priorities/priorities.py", line 52, in
addItem
item = Priority(subject = g.textBox.get("1.0", 'end-1c'), priority = g.textBox.get("1.0", 'end-1c')) AttributeError: 'GuiPart' object has no attribute 'textBox'
Process finished with exit code 0
Here is what I have done:
# priorities.py
# GUI program to manage priorities
from tkinter import *
class Priority:
def __init__(self, subject, priority):
self.subject = subject
self.priority = priority
def subject(self):
return self.subject
def priority(self):
return self.priority
class GuiPart:
def __init__(self):
self.root = self.createWindow()
def createWindow(self):
root = Tk()
root.resizable(width = False, height = False)
root.title("Priorities")
return root
def createWidgets(self):
Button(self.root,
text = "Add",
command = self.addItem).grid(row = 2, column = 0, sticky = W + E)
Button(self.root,
text="Remove",
command = self.removeItem).grid(row = 2, column = 1, sticky = W + E)
Button(self.root,
text="Edit",
command = self.editItem).grid(row = 2, column = 2, sticky = W + E)
listBox = Listbox(width = 30).grid(row = 1, sticky = W + E, columnspan = 3)
textBox = Text(height=10, width=30).grid(row = 3, columnspan = 3, sticky = W + E + N + S)
def addItem(self):
item = Priority(subject = g.textBox.get("1.0", 'end-1c'), priority = g.textBox.get("1.0", 'end-1c'))
g.listBox.insert(END, item)
def removeItem(self):
pass
def editItem(self):
pass
class Client:
pass
if __name__ == "__main__":
g = GuiPart()
g.createWidgets()
g.root.mainloop()
I'm using Python 3.5.
So if I understood your aim, you are trying to describe a priority by allowing the user to type, within the text zone widget, its information which consists in its subject and order; after that, the user can click on the "Add" button to insert the priority information into your list box.
There are lot of things to consider around your code. If I go to fix and comment them one by one, I believe my answer will be long while I feel lazy today.
I think my program below is easy to understand (ask a clarification otherwise). I did not find specifications inherent to how the propriety information is typed in the text zone. So my program below works under the assumption the user types the priority subject on the first line of the text area, and then uses a new line to type the priority order. The click on "Add" button will lead to the insertion of these 2 data on the same line of the text box widget as shown below:
Here is an MCVE:
import tkinter as tk
class ProioritiesManager(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.master = master
self.master.resizable(width = False, height = False)
self.master.title("Priorities")
self.create_buttons()
self.create_listbox()
self.create_priorities_description_zone()
def create_buttons(self):
add_item = tk.Button(self.master, text='Add', command=self.add_item)
add_item.grid(row=2, column=0, sticky=tk.W+tk.E)
remove_item = tk.Button(self.master, text='Remove', command=self.remove_item)
remove_item.grid(row=2, column=1, sticky=tk.W+tk.E)
edit_item = tk.Button(self.master, text='Edit', command=self.edit_item)
edit_item.grid(row=2, column=2, sticky=tk.W+tk.E)
def create_listbox(self):
self.item_alternatives = tk.Listbox(self.master, width=30)
self.item_alternatives.grid(row=1, sticky=tk.W+tk.E, columnspan=3)
def create_priorities_description_zone(self):
self.priority_text_zone = tk.Text(self.master, height=10, width=30)
self.priority_text_zone.grid(row=3, columnspan=3, sticky=tk.W+tk.E+tk.N+tk.S)
def get_priority_subject(self):
return self.priority_text_zone.get('1.0', '1.0 lineend')
def get_priority_order(self):
return self.priority_text_zone.get('2.0', '2.0 lineend')
def add_item(self):
self.item_alternatives.insert(tk.END, self.get_priority_subject()+' '+ self.get_priority_order())
def remove_item(self):
pass
def edit_item(self):
pass
if __name__ == "__main__":
root = tk.Tk()
ProioritiesManager(root)
root.mainloop()
If you want to give a good UX to your GUI then it would be nice if you add a button to allow the user to clear the content of the text area so that he can type in a new priority:
For this purpose, you can add a rest button to create_buttons() function by adding these 2 lines of code:
clear_text_area = tk.Button(self.master, text='Reset', command=self.reset_priority_text_zone)
clear_text_area.grid(row=4, column=2)
The callback reset_priority_text_zone() is defined this way:
def reset_priority_text_zone(self):
self.priority_text_zone.delete('1.0', tk.END)
These Lines are causing Error :
listBox = Listbox(width = 30).grid(row = 1, sticky = W + E, columnspan = 3)
textBox = Text(height=10, width=30).grid(row = 3, columnspan = 3, sticky = W + E + N + S)
Do it like this:
self.listBox = Listbox(self.root,width = 30)
self.listBox.grid(row = 1, sticky = W + E, columnspan = 3)
self.textBox = Text(self.root,height=10, width=30)
self.textBox.grid(row = 3, columnspan = 3, sticky = W + E + N + S)
Actually you are not creating listBox and textBox objects instead grid is returning to listBox and textBox
so I'm coding this GUI-program (using tkinter) and I'm using three Entryboxes in the same function. I wanna use their values in the main function, so how do I get the values into some kind of global variable or in a way that I can use them in a different function?
def options():
options_root = Tk()
textFrame = Frame(options_root)
textFrame.grid()
widthlabel = Label(textFrame, text="w:", justify=LEFT)
widthlabel.grid(column="0", row="0")
widthinput = Entry(textFrame)
widthinput.grid(column="1", row="0")
heightlabel = Label(textFrame, text="h:", justify=LEFT)
heightlabel.grid(column="0", row="1")
heightinput = Entry(textFrame)
heightinput.grid(column="1", row="1")
mlabel = Label(textFrame, text="m:", justify=LEFT)
mlabel.grid(column="0", row="2")
minput = Entry(textFrame)
minput.grid(column="1", row="2")
width = widthinput.get()
height = heightinput.get()
m = minput.get()
start_game_button = Button(options_root, text="Start", justify=LEFT, command=lambda:tabort(options_root))
start_game_button.grid(column="0",row="3")
exit_button = Button(options_root, text = "Exit", justify=LEFT, command=exit)
exit_button.grid(column="1", row="3")
mainloop()
def main():
options()
w = widthinput.get()
h = heightinput.get()
m = minput.get()
main()
Keep a reference to the widgets, then use the get() method. This becomes much easier if you design your application as a class:
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self, ...):
...
self.width_entry = tk.Entry(...)
self.height_entry = tk.Entry(...)
self.minput_entry = tk.Entry(...)
...
def main(...):
w = self.width_entry.get()
h = self.height_entry.get()
m = self.input_entry.get()
...
...
app = SampleApp()
app.mainloop()