I am trying to make the radio buttons change the position of the entry field (called assignment)
what i expected was for it to grid it next to the button but instead i get this error
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tkinter/__init__.py", line 1702, in __call__
return self.func(*args)
File "<string>", line 16, in <lambda>
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tkinter/__init__.py", line 2223, in grid_configure
+ self._options(cnf, kw))
_tkinter.TclError: bad window path name ".!application.!entry"`
the issue is on line 16 with the lambda function
ive tried making the variable in the function, i've also tried having it run exec.
here is the code
from tkinter import *
import random
class application(Frame):
def __init__(self,master ):
Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self, ):
assignment = Entry(self)
for i in self.winfo_children():
i.destroy()
self.var = IntVar()
for i in range(8):
Radiobutton(self, text = ('class ' + str(i + 1)), variable = self.var, value = (i+1), command = lambda i = i: assignment.grid()).grid(row = i, column = 1)
for i in range(8):
exec('class' + str(i) + ' = Label(self, text = \'34\')\nclass' + str(i) + '.grid(row = '+str(i)+',column = 3)')
print(self.var.get())
root = Tk()
root.title('dumb kid idiot test')
root.geometry('500x500')
app = application(root)
root.mainloop()
I am not sure why you are using exec
to create a label. There is a much safer way to do this just like your raidiobutton.
One major problem you have is you are not using i
that you define in your lambda. Nothing can be updated if you do not apply that value to the grid.
Also this code is destroying your entry field right away.
for i in self.winfo_children():
i.destroy()
I cleaned up your example a bit and fixed the lambda issue.
Try this:
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.geometry('300x225')
self.title('dumb kid idiot test')
self.entry = tk.Entry(self)
self.var = tk.IntVar(self)
for i in range(8):
tk.Radiobutton(self, text=('class ' + str(i + 1)), variable=self.var, value=(i+1),
command=lambda i=i: self.entry.grid(row=i, column=4)).grid(row=i, column=1)
for i in range(8):
tk.Label(self, text='34').grid(row=i, column=3)
if __name__ == '__main__':
App().mainloop()
You may also want a function/method to handle the grid chance just in case you also want your button to do other things when clicked.
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.geometry('300x225')
self.title('dumb kid idiot test')
self.entry = tk.Entry(self)
self.var = tk.IntVar(self)
for i in range(8):
tk.Radiobutton(self, text=('class ' + str(i + 1)), variable=self.var, value=(i+1),
command=lambda i=i: self.move_entry(i)).grid(row=i, column=1)
for i in range(8):
tk.Label(self, text='34').grid(row=i, column=3)
def move_entry(self, ndex):
self.entry.grid(row=ndex, column=4)
if __name__ == '__main__':
App().mainloop()
Let's look at this code:
def create_widgets(self, ):
assignment = Entry(self)
for i in self.winfo_children():
i.destroy()
You are creating an entry widget, and then you almost immediately delete it since it is a child of self
. Therefore, any code that later tries to use or modify the widget will fail with the exact error you are giving it.
If you plan on using the entry, don't delete it. You can do that in a couple of ways:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.