Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 2.7 Tkinter在destroy()上的奇怪行为_Python 2.7_Tkinter - Fatal编程技术网

Python 2.7 Tkinter在destroy()上的奇怪行为

Python 2.7 Tkinter在destroy()上的奇怪行为,python-2.7,tkinter,Python 2.7,Tkinter,我正在Tkinter、Python2.7上开发一个应用程序。 在我的一个过程中,我用26个小部件构建了一部分窗口(根): 23个标签、2个按钮和1个条目。 在建造它们的过程中,我不断将它们的名字添加到列表中,以便进一步销毁 当他们使用完毕。为此,我使用按下其中一个按钮(“完成”) 读取创建的列表并在“for”循环中销毁它们。 小部件会不规则地被销毁,而不是按列表上的顺序销毁。我需要 按几下按钮就完成了。 我沮丧地发现,如果列表在 “for”循环在第一次尝试时都会被“销毁”。 这是预期的行为吗?非

我正在Tkinter、Python2.7上开发一个应用程序。 在我的一个过程中,我用26个小部件构建了一部分窗口(根): 23个标签、2个按钮和1个条目。 在建造它们的过程中,我不断将它们的名字添加到列表中,以便进一步销毁 当他们使用完毕。为此,我使用按下其中一个按钮(“完成”) 读取创建的列表并在“for”循环中销毁它们。 小部件会不规则地被销毁,而不是按列表上的顺序销毁。我需要 按几下按钮就完成了。 我沮丧地发现,如果列表在 “for”循环在第一次尝试时都会被“销毁”。 这是预期的行为吗?非常令人费解! 我已经准备好发布我的应用程序中带有奇怪行为的部分 删除不必要的代码,除非有人已经知道原因。 我仍然在努力学习Python,还没有准备好使用类。。。 谢谢大家!

我包括我的课程的相关部分。我编辑了原稿以缩小它的尺寸。已测试编辑的版本,它具有相同的行为。我对一些代码进行了注释,以显示在哪里进行更正。 很高兴奥克利先生感兴趣。我不确定在转录代码时,正确的缩进是否没有受到影响

我的代码:

# testdestroy.py
from Tkinter import *
root = Tk()
root.title('Information container')
root.geometry('1160x900+650+50')

global todestroy, screen, font1, lbl1txt, lbl2txt
global col, row, colincr, rowincr, bxincr, entries

todestroy = []
screen = ''
col = 10
row = 10
font1 = 'verdana 12 bold '
colincr = 370
rowincr = 40
bxincr = 145

entries = {' Last updated: ' : '11/08/2016 at 11:55',
            ' Login id: ' : 'calfucura',
            ' Password: ': 'munafuca',
            'card number' : '1234567890',
            'check number': '445',
            'expiry' : '12/06/2018',
            'PIN' : '9890', 
            'Tel:' : '1-800-234-5678',
            'emergency' : 'entry nine',
            'use for' : 'gas, groceries'}

def position(col, row, what):       # returns the position for the place command
    colincr = 370
    rowincr = 40
    bxincr = 145
    if what == 'down':
        row += rowincr
        col -= colincr
    if what == 'side':
        col += colincr
    if what == 'button1':
        row += rowincr
        col += colincr - bxincr
    if what == 'button':
        col -= bxincr
    if what == 'reset':
        col = col
        row = row
    return col, row

def done(event):                        #  Button "Done"
    print 'Done pressed'
    for name in todestroy:     # DOES NOT WORK!!!!
                               # THIS WORKS in the previous line: 
                               # for name in reversed(todestroy):
        name.destroy()
        todestroy.remove(name)

def accept(event):                      # Button "Accept"
    print 'Name to show: ', entry1.get()
    scr2d1(entries)

def scr2d():                            # Name to show
    lbl1txt = 'Enter name to show: '
    screen = 'scr2d'
    scr2(lbl1txt)
#    scr2d1(entries)

def scr2(lbl1txt):
    global todestroy, col, row, entry1
    lbl1 = Label(root, text = lbl1txt, anchor = E, width = 25, font = font1)
    entry1 = Entry(root, width = 25, show = '*', font = font1)
    Accept = Button(root, text = 'Accept', font = font1, bg = 'green', width = 9)
    cmd = eval('Accept'.lower())
    Accept.bind('<ButtonRelease-1>', cmd)
    col, row = position(200, 200, 'reset')
    lbl1.place(x = col, y = row)
    col, row = position(col, row, 'side')
    entry1.place(x = col , y = row )
    col, row = position(col, row, 'button1')
    Accept.place(x = col, y = row)
    todestroy = []
    todestroy.extend([lbl1, entry1, Accept])

def scr2d1(entries):                # show entries
    global todestroy, col, row
    lblup = 1
    lbl = 'lbl' + str(lblup)
    lbl = Label(root, text = 'Entry', font = font1, width = 20 )
    row = rowincr * 7
    col = 600
    col, row = position(col, row, 'down')
    lbl.place(x = col, y = row)
    todestroy.append(lbl)
    lblup += 1
    lbl = 'lbl' + str(lblup)
    lbl = Label(root, text = 'Contents', font = font1, width = 20)
    col, row = position(col, row, 'side')
    lbl.place (x = col, y = row)
    todestroy.append(lbl)
    for name in sorted(entries):
        lblup += 1
        lbl = 'lbl' + str(lblup)
        lbl = Label(root, text = name, bg = 'yellow', font = font1, width = 25, anchor = E)
        col, row = position(col, row, 'down')
        lbl.place(x = col, y = row)
        todestroy.append(lbl)
        lblup += 1
        lbl = 'lbl' + str(lblup)
        lbl = Label(root, text = entries[name], bg = 'yellow', font = font1, width = 25, anchor = W)
        col, row = position(col, row, 'side')
        lbl.place(x = col , y = row)
        todestroy.append(lbl)
    cmd = eval('done')
    Done = Button(root, text = 'Done', font = font1, bg = 'green', width = 9)
    Done.bind('<ButtonRelease-1>', cmd)
    col, row = position(col, row, 'button1')
    Done.place(x = col, y = row)
    todestroy.append(Done)

scr2d()

root.mainloop()       
#testdestroy.py
从Tkinter进口*
root=Tk()
root.title('信息容器')
根几何体('1160x900+650+50')
全局todestroy、屏幕、font1、lbl1txt、lbl2txt
全局列,行,列号,列号,列号,bxincr,条目
todestroy=[]
屏幕=“”
col=10
行=10
font1='verdana 12 bold'
colincr=370
rowincr=40
bxincr=145
条目={“上次更新:”:“2016年8月11日11:55”,
'登录id:':'calfucura',
'密码:':'munafuca',
“卡号”:“1234567890”,
“支票号码”:“445”,
“到期日”:2018年6月12日,
‘PIN’:‘9890’,
‘电话:’:‘1-800-234-5678’,
“紧急情况”:“第九次进入”,
“用于”:“煤气、食品”}
def position(列、行、内容):#返回place命令的位置
colincr=370
rowincr=40
bxincr=145
如果what==‘down’:
行+=行增量
col-=colincr
如果what=='side':
col+=colincr
如果what==“button1”:
行+=行增量
col+=colincr-bxincr
如果what==“按钮”:
col-=bxincr
如果what==“重置”:
col=col
行=行
返回列
定义完成(事件):#按钮“完成”
打印“已按完成”
对于todestroy中的名称:#不起作用!!!!
#这在前一行中起作用:
#对于反向(todestroy)中的名称:
name.destroy()
todestroy.remove(名称)
def接受(事件):#按钮“接受”
打印“要显示的名称:”,entry1.get()
scr2d1(条目)
def scr2d():#要显示的名称
lbl1txt='输入要显示的名称:'
屏幕='scr2d'
scr2(lbl1txt)
#scr2d1(条目)
def scr2(lbl1txt):
全球todestroy、col、row、entry1
lbl1=标签(根,文本=lbl1txt,锚定=E,宽度=25,字体=font1)
entry1=Entry(根,宽度=25,显示='*',字体=font1)
Accept=按钮(根,文本='Accept',字体=font1,背景='green',宽度=9)
cmd=eval('Accept'.lower())
Accept.bind(“”,cmd)
列,行=位置(200,200,‘重置’)
lbl1.位置(x=列,y=行)
col,row=位置(col,row,'侧面')
entry1.place(x=col,y=row)
col,row=位置(col,row,'按钮1')
Accept.place(x=col,y=row)
todestroy=[]
todestroy.extend([lbl1,entry1,Accept])
def scr2d1(条目):#显示条目
全球todestroy、col、row
lblup=1
lbl='lbl'+str(lblup)
lbl=标签(根,文本='Entry',字体=font1,宽度=20)
行=rowincr*7
col=600
列,行=位置(列,行,“向下”)
lbl.位置(x=列,y=行)
todestroy.append(lbl)
lblup+=1
lbl='lbl'+str(lblup)
lbl=标签(根,文本='Contents',字体=font1,宽度=20)
col,row=位置(col,row,'侧面')
lbl.place(x=列,y=行)
todestroy.append(lbl)
对于排序中的名称(条目):
lblup+=1
lbl='lbl'+str(lblup)
lbl=标签(根,文本=名称,背景=黄色,字体=字体1,宽度=25,锚定=E)
列,行=位置(列,行,“向下”)
lbl.位置(x=列,y=行)
todestroy.append(lbl)
lblup+=1
lbl='lbl'+str(lblup)
lbl=标签(根,文本=条目[名称],背景='黄色',字体=font1,宽度=25,锚定=W)
col,row=位置(col,row,'侧面')
lbl.位置(x=列,y=行)
todestroy.append(lbl)
cmd=eval('done')
完成=按钮(根,文本='Done',字体=font1,背景='green',宽度=9)
完成。绑定(“”,cmd)
col,row=位置(col,row,'按钮1')
完成。放置(x=列,y=行)
todestroy.append(完成)
scr2d()
root.mainloop()

问题在于,在迭代列表时,您正在更改列表,这不是您应该做的事情。它与
reversed
一起工作的原因是您正在迭代原始列表的副本。如果在todestroy[:]中对name使用
,则会得到相同的结果,这也会对列表的副本进行迭代

最快的解决方案是不从列表中删除任何内容,只需在删除所有内容后重置列表:

def done(event): 
    global todestroy
    for name in todestroy:
        name.destroy()
    todestroy = []

更好的解决方案是将您计划销毁的所有小部件放在
框架中
。然后,您可以只销毁框架,它将销毁其所有子部件。

请阅读。不要发布“应用程序的一部分”。相反,把它简化成一个小的、可以工作的程序来说明这个问题。你是否意识到删除一个小部件会破坏它以及它的所有子部件