2016-08-12 1 views
-1

私はTkinter、Python 2.7でアプリケーションを開発しています。 私のプロセスの1つでは、26個のウィジェットを持つウィンドウ(ルート)の一部を構築します: 23ラベル、2ボタン、および1エントリ。 それらを構築している間、彼らの名前がリストに追加され続け、使用が終了するとさらに破壊するために が破壊されます。そのために、ボタンの1つ( "Done") を使って、作成されたリストを読み込み、 "for"ループ内でdestroy()します。 ウィジェットは、リスト上の順序ではなく、不規則に破壊されます。そして、私はそれを完了するためにボタンのいくつかのプレス が必要です。 の "for"ループでリストが反転されていると、最初の試みですべてが "破棄"されるという洞察ではなく、不満から分かりました。 これは正常な動作ですか?非常に混乱している! 私のアプリケーションの一部を投稿する準備が整いました 誰かがそれの理由を知っていない限り、不必要なコードが削除されました。 私はまだPythonで私のチョップを破って、クラスを使用する準備ができていません... ありがとう!Tkinter destroy()の異常な動作

私は自分のプログラムの関連部分を含めています。オリジナルを編集してサイズを小さくしました。テストされたバージョンをテストし、同じ動作をします。私は、コードのいくつかを修正する場所を示すためにコメントしました。 オークリー氏が関心を寄せてくれてうれしいです。適切な字下げが影響を受けないかどうかわかりません。

マイコード:

# 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()  
+0

http://www.stackoverflow.com/help/mcveをお読みください。 「あなたのアプリケーションの一部」を投稿しないでください。代わりに、問題を示す小さな作業プログラムに減らしてください。 –

+0

あなたは、ウィジェットを削除するとそのウィジェットとそのすべての子が破棄されることにご注意ください。ウィジェットを1つずつ破棄する必要はありません。 –

+0

@BryanOakley私は単一のルートウィンドウとフレームなしでプログラムを設計しました。私はすべてのことのためにそのルートウィンドウを保持します。私のコードを使用するには、 "表示する名前"に任意の文字を入力し、 "同意"を押してください。おそらく私は "コードsepuku"をコミットしていますが...私はTkinterで始まり、まだ管理できないフレームを見つけました。ありがとう! – Albert

答えて

1

問題は、あなたがすべきものではありませんこれは、あなたがそれを反復としてリストを変更しているということです。 reversedで動作する理由は、元のリストのコピーを反復処理するためです。 for name in todestroy[:]を使用すると同じ結果が得られます。もリストのコピーを反復処理します。

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

は、よりよい解決策は、あなたが破壊することを計画してウィジェットのすべてを置くために、次のようになります。あなたはすべてを削除した後

最速のソリューションは、リストから何かを削除し、単にリストをリセットしないことですFrameにフレームを破棄すると、その子ウィジェットのすべてが破棄されます。

+0

@BrianOakleyあなたは応答する時間がかかったことをうれしく思います。私のリストについての素晴らしい点!私はフレームを使用しようとしましたが、アイテムを配置する際に問題がありました。なぜなら、ウィジェットを置いたときにだけフレームが大きくなり、デバッグの瞬間にその結果を見るのは難しいからです。私は私がやっていることにもっと自信があるときにフレームを別のものにします。これがTkinterでの私の最初の試みです。多くのおかげで、私は "謎"が好きではありません... – Albert

関連する問題