I am creating an application in which, when you click on a button in the menu section (called "command"), a second window should open for additional calculations.
我正在创建一个应用程序,当你点击菜单部分的按钮(称为“命令”)时,应该会打开第二个窗口进行额外的计算。
I have such a problem: when I open the second window for the first time (win 2) - it works fine, but when I close it and open it again - I can't switch between input fields using the keys that I specified, although I could for the first time. Returns the following error: "_tkinter.TclError: can't invoke "focus" command: application has been destroyed".
我遇到了这样一个问题:当我第一次打开第二个窗口(win 2)时,它运行良好,但当我关闭它并再次打开它时,我无法使用我指定的键在输入字段之间切换,尽管我第一次可以。返回以下错误:“_tkinter.TclError:无法调用“焦点”命令:应用程序已被销毁”。
If I open this window and open the same window again on top of it, I start switching between the input fields and these two windows.
如果我打开这个窗口,并在它上面再次打开同一个窗口,我就会开始在输入字段和这两个窗口之间切换。
Tell me, what could be the problem here and how to solve it? I don't have much experience, I would be very grateful for a clear answer, and help in general. Thank you.
告诉我,这里可能有什么问题,如何解决?我没有太多经验,如果能有一个明确的答案和一般的帮助,我将不胜感激。非常感谢。
Вот мой код:
В:
from tkinter import *
from tkinter import ttk
def o_downKey(event):
o_handle = event.widget.focus_get()
o_lstHandle[(o_lstHandle.index(o_handle) + 1)%len(o_lstHandle)].focus()
def o_upKey(event):
o_handle = event.widget.focus_get()
o_lstHandle[(o_lstHandle.index(o_handle) - 1)%len(o_lstHandle)].focus()
def new_win():
def win2_downKey(event):
win2_handle = event.widget.focus_get()
win2_lstHandle[(win2_lstHandle.index(win2_handle) + 1)%len(win2_lstHandle)].focus()
def win2_upKey(event):
win2_handle = event.widget.focus_get()
win2_lstHandle[(win2_lstHandle.index(win2_handle) - 1)%len(win2_lstHandle)].focus()
win2 = Tk()
win2.title('Расчет квадратуры')
win2.geometry('300x185+600+190')
win2.resizable(0,0)
lbl_up = Label(win2, text = 'win2 label', font = 'normal, 13')
lbl_up.place(x=5, y=7)
lbl_kk = Label(win2, text = 'win2 labl', font = 'normal, 13')
lbl_kk.place(x=5, y=34)
ent_up = Entry(win2, font = 'noraml, 13',borderwidth=3, relief="ridge")
win2_lstHandle.append(ent_up)
ent_up.bind('<Left>', win2_downKey)
ent_up.bind('<Right>', win2_upKey)
ent_up.bind('<Return>', win2_upKey)
ent_up.place(width=85, x=127, y=6)
ent_kk = Entry(win2, width = 18, font = 'noraml, 13',borderwidth=3, relief="ridge")
win2_lstHandle.append(ent_kk)
ent_kk.bind('<Left>', win2_downKey)
ent_kk.bind('<Right>', win2_upKey)
ent_kk.bind('<Return>', win2_upKey)
ent_kk.place(x=127, y=34)
ent_up1 = Entry(win2, font = 'noraml, 13',borderwidth=3, relief="ridge")
win2_lstHandle.append(ent_up1)
ent_up1.bind('<Left>', win2_downKey)
ent_up1.bind('<Right>', win2_upKey)
ent_up1.bind('<Return>', win2_upKey)
ent_up1.place(width=85, x=212, y=6)
win = Tk()
win.title("CFS")
win.geometry('500x310+500+200')
win.resizable(0, 0)
o_lstHandle = []
win2_lstHandle = []
mainmenu = Menu(win)
win.config(menu=mainmenu)
filemenu = Menu(mainmenu, tearoff=0)
filemenu.add_command(label="1", command = new_win)
filemenu_1 = Menu(mainmenu, tearoff=0)
filemenu_1.add_command(label="1")
filemenu_1.add_command(label="2")
filemenu_1.add_command(label="3")
mainmenu.add_cascade(label="command", menu=filemenu)
mainmenu.add_cascade(label = 'command 2', menu = filemenu_1)
frame = ttk.Frame(win, relief="groove", borderwidth = 0)
frame.pack(expand=1, fill='both')
tab_control = ttk.Notebook(frame)
tab1 = ttk.Frame(relief="groove", borderwidth = 1)
tab3 = ttk.Frame(relief="groove", borderwidth = 1)
tab4 = ttk.Frame(relief="groove", borderwidth = 1)
s = ttk.Style()
s.configure('TNotebook.Tab', font='normal, 10')
tab_control.add(tab1, text='tab1')
tab_control.add(tab3, text='tab2')
tab_control.add(tab4, text='tab3')
tab_control.pack(expand=1, fill='both', padx=1,pady=1)
o_ent1 = Entry(tab1, width=8, font = 'noraml, 13',borderwidth=3, relief="ridge")
o_lstHandle.append(o_ent1)
o_ent1.bind('<Down>', o_downKey)
o_ent1.bind('<Up>', o_upKey)
o_ent1.bind('<Return>', o_downKey)
o_ent1.place(x=115,y=15)
o_ent2 = Entry(tab1, width=8, font = 'noraml, 13',borderwidth=3, relief="ridge")
o_lstHandle.append(o_ent2)
o_ent2.bind('<Down>', o_downKey)
o_ent2.bind('<Up>', o_upKey)
o_ent2.bind('<Return>', o_downKey)
o_ent2.place(x=115,y=41)
o_ent3 = Entry(tab1, width=8, font = 'noraml, 13',borderwidth=3, relief="ridge")
o_lstHandle.append(o_ent3)
o_ent3.bind('<Down>', o_downKey)
o_ent3.bind('<Up>', o_upKey)
o_ent3.bind('<Return>', o_downKey)
o_ent3.place(x=115,y=67)
o_ent4 = Entry(tab1, width=8, font = 'noraml, 13',borderwidth=3, relief="ridge")
o_lstHandle.append(o_ent4)
o_ent4.bind('<Down>', o_downKey)
o_ent4.bind('<Up>', o_upKey)
o_ent4.bind('<Return>', o_downKey)
o_ent4.place(x=115,y=93)
o_ent5 = Entry(tab1, width=8, font = 'noraml, 13',borderwidth=3, relief="ridge")
o_lstHandle.append(o_ent5)
o_ent5.bind('<Down>', o_downKey)
o_ent5.bind('<Up>', o_upKey)
o_ent5.bind('<Return>', o_downKey)
o_ent5.place(x=115,y=119)
o_ent6 = Entry(tab1, width=8, font = 'noraml, 13',borderwidth=3, relief="ridge")
o_lstHandle.append(o_ent6)
o_ent6.bind('<Down>', o_downKey)
o_ent6.bind('<Up>', o_upKey)
o_ent6.bind('<Return>', o_downKey)
o_ent6.place(x=115,y=145)
o_lb1 = Label(tab1, text='label 1', font = 'noraml, 13')
o_lb1.place(x=15,y=15)
o_lb2 = Label(tab1, text='label 2', font = 'noraml, 13')
o_lb2.place(x=15,y=41)
o_lb3 = Label(tab1, text='label 3', font = 'noraml, 13')
o_lb3.place(x=15,y=67)
o_lb4 = Label(tab1, text='label 4', font = 'noraml, 13')
o_lb4.place(x=15,y=93)
o_lb5 = Label(tab1, text='label 5', font = 'noraml, 13')
o_lb5.place(x=15,y=119)
o_lb6 = Label(tab1, text='label 6', font = 'noraml, 13')
o_lb6.place(x=15,y=145)
otkr_knop = Button(tab1, text = 'Button 1', font = 'noraml, 13', borderwidth=3, relief="ridge")
otkr_knop.place(x=10,y=230)
o_ochist = Button(tab1, text = 'Button 2', font = 'noraml, 13', borderwidth=3, relief="ridge")
o_ochist.place(x=110,y=230)
canvas = Canvas(tab1, bg="white", width=280, height=258, relief=GROOVE, bd=3)
canvas.pack(anchor = SE)
tpk1 = Label(tab1, text = 'text"', font = 'Arial 9 bold roman', fg='blue')
tpk1.place(x=402,y=264)
mytex = canvas.create_text(150, 135, text="")
win.mainloop()
更多回答
Creating more than one instance of Tk
usually causes more problems than it solves. Is there a specific reason you're doing that instead of using Toplevel
for all windows except the root window?
创建多个Tk实例通常会导致比解决问题更多的问题。你这样做而不是对除根窗口之外的所有窗口使用Toplevel,有什么具体原因吗?
I can't reproduce the problem on my machine...
我无法在我的机器上重现这个问题。。。
The situation with Toplevel
is exactly the same
Toplevel的情况完全相同
It is because you have used same global variable win2_lstHandle
to store the references of those Entry
widgets in the new window created. The calculation of the next widget to be focused works when first window created. However after the first window is destroyed and second new window is created, the size of win2_lstHandle
will be 6 instead of 3, so the calculation of the next widget to be focused is wrong and point to the destroyed Entry
widget in the first window. You can use an attribute of the new window instead of global variable.
这是因为您在创建的新窗口中使用了相同的全局变量win2_lstHandle来存储这些Entry小部件的引用。在创建第一个窗口时,下一个要关注的小部件的计算工作正常。然而,在第一个窗口被破坏并创建第二个新窗口后,win2_lstHandle的大小将是6而不是3,因此下一个要关注的小部件的计算是错误的,并指向第一个窗口中被破坏的Entry小部件。您可以使用新窗口的属性而不是全局变量。
@acw1668 Can you demonstrate how this can be done ?
@acw1668你能演示一下如何做到这一点吗?
It is because you have used same global variable win2_lstHandle
to store the references of those Entry
widgets in the new window created. The calculation of the next widget to be focused works when first window is created. However after the first window is destroyed and second new window is created, the size of win2_lstHandle
will be 6 instead of 3, so the calculation of the next widget to be focused is wrong and point to the destroyed Entry
widget in the first window.
这是因为您在创建的新窗口中使用了相同的全局变量win2_lstHandle来存储这些Entry小部件的引用。当创建第一个窗口时,下一个要关注的小部件的计算就开始了。然而,在第一个窗口被破坏并创建第二个新窗口后,win2_lstHandle的大小将是6而不是3,因此下一个要关注的小部件的计算是错误的,并指向第一个窗口中被破坏的Entry小部件。
You can use an attribute of the new window instead of global variable. Below is the modified new_win()
using an attribute instead of global variable to store the entry widgets:
您可以使用新窗口的属性而不是全局变量。下面是修改后的new_win(),它使用属性而不是全局变量来存储入口小部件:
def new_win():
def win2_downKey(event):
win2_handle = event.widget.focus_get()
win2.lstHandle[(win2.lstHandle.index(win2_handle) + 1)%len(win2.lstHandle)].focus()
def win2_upKey(event):
win2_handle = event.widget.focus_get()
win2.lstHandle[(win2.lstHandle.index(win2_handle) - 1)%len(win2.lstHandle)].focus()
# better use Toplevel() instead of Tk() for child window
win2 = Toplevel()
win2.title('Расчет квадратуры')
win2.geometry('300x185+600+190')
win2.resizable(0,0)
lbl_up = Label(win2, text = 'win2 label', font = 'normal, 13')
lbl_up.place(x=5, y=7)
lbl_kk = Label(win2, text = 'win2 labl', font = 'normal, 13')
lbl_kk.place(x=5, y=34)
win2.lstHandle = [] # use an attribute to store the references of entry widgets
ent_up = Entry(win2, font = 'noraml, 13',borderwidth=3, relief="ridge")
win2.lstHandle.append(ent_up)
ent_up.bind('<Left>', win2_downKey)
ent_up.bind('<Right>', win2_upKey)
ent_up.bind('<Return>', win2_upKey)
ent_up.place(width=85, x=127, y=6)
ent_kk = Entry(win2, width = 18, font = 'noraml, 13',borderwidth=3, relief="ridge", bg="gold")
win2.lstHandle.append(ent_kk)
ent_kk.bind('<Left>', win2_downKey)
ent_kk.bind('<Right>', win2_upKey)
ent_kk.bind('<Return>', win2_upKey)
ent_kk.place(x=127, y=34)
ent_up1 = Entry(win2, font = 'noraml, 13',borderwidth=3, relief="ridge")
win2.lstHandle.append(ent_up1)
ent_up1.bind('<Left>', win2_downKey)
ent_up1.bind('<Right>', win2_upKey)
ent_up1.bind('<Return>', win2_upKey)
ent_up1.place(width=85, x=212, y=6)
Or simply use a local variable instead:
或者只需使用局部变量:
def new_win():
# create a local variable
win2_lstHandle = []
...
更多回答
Thank you very much!! You, with your really useful and detailed answers, help me out for the second time
非常感谢!!你,用你真正有用和详细的答案,第二次帮助我
@shbidibom If it solves your issue, upvote and accept it as the answer to show your appreciation.
@shbidbom如果它解决了你的问题,请投赞成票并接受它作为表示感谢的答案。
我是一名优秀的程序员,十分优秀!