2017-09-14 1 views
1

私は、次のように 'for'ループを使って4列のテキストウィジェットを作成しました。 enter image description heretkinterのTextウィジェットで値を消去したときにリストから値を削除するには?

私の目標は、だから私はに価値を付加しているタブのキーと機能を結合し、lambdaを使用して
list1 =[]list2=[]list3=[]list4=[]

のように異なるリスト内の各およびすべてのテキストウィジェットの列の値を追加することですその特定のリスト。これまでのところうまく動作します。 enter image description here

enter image description here



私は(例えば、第二列2列目の値 - 764)を誤って間違った値を入力した場合今の問題は、「タブ」がバインドされているので、それはまた、リストに追加されます。

私はいくつかの計算目的のためにこれらのリストを作成しているので、間違いなく計算が損なわれます。ユーザーは間違いなく入力することができません。

私はテキストをクリアし、以前に格納されていたリストの値を変更する方法が必要です。テキストウィジェットで変更されると、リスト内で変更する必要があります。

MY CODE:

from tkinter import * 

list1 = [] 
list2 = [] 
list3 = [] 
list4 = [] 

def testfunction(var): 
    print(var) 
    list1.append(var) 

def testfunction2(var): 
    print(var) 
    list2.append(var) 

def testfunction3(var): 
    print(var) 
    list3.append(var) 

def testfunction4(var): 
    print(var) 
    list4.append(var) 


root = Tk() 

for _ in range(3): 
    t = StringVar() 
    t1 = IntVar() 
    t2 = IntVar() 
    t3 = IntVar() 

    ent = Entry(root, textvariable=t) 
    ent.bind("<Tab>",(lambda event, ent=ent:testfunction(ent.get()))) 
    ent.grid(row=_, column=0) 

    ent2 = Entry(root, textvariable=t1) 
    ent2.bind("<Tab>",(lambda event, ent2=ent2:testfunction2(ent2.get()))) 
    ent2.grid(row=_, column=1) 

    Rat = Entry(root, textvariable=t2) 
    Rat.bind("<Tab>",(lambda event, Rat=Rat:testfunction3(Rat.get()))) 
    Rat.grid(row=_, column=2) 

    amt = Entry(root, textvariable=t3) 
    amt.bind("<Tab>",(lambda event, amt=amt:testfunction4(amt.get()))) 
    amt.grid(row=_, column=3) 


root.mainloop() 
+0

たぶんEntry'はそれに必要な動作を与えるために、 'サブクラス? –

+1

これは根本的に壊れているユーザーインターフェイスです。ユーザーが特定の順序でフィールドに入力する必要があります。これは、誰かがGUIを動作させる方法ではありません。それらの 'textvariable'をリストにすべて保存する必要があります。これにより、値が入力された順序とはまったく無関係に、計算を実行するときにそれらをすべて取得することができます。 – jasonharper

+0

@jasonharper私はあなたのことを理解しています。この場合、私に例を教えてください。どのように私はそれをユーザーフレンドリーにすることができますか? – Sundararajan

答えて

2

私はあなたの代わりにtkinter.Texttkinter.Entryウィジェットを使用することを示唆しています。 これらは、オプションのパラメータtextvariableをサポートしています。これは、変数を受け取ることができ、トレース可能になります。

変数はtkinter.Variableクラスのインスタンスです。 より正確には、それは前者を拡張するtk.StringVarクラスの1つになります。 エントリの内容に関するハンドルを提供します:現在の入力の値を保持するように、常に自動的に更新されます。

ここで私は行く:まず、変数の行列とエントリの行列を作成する。 わかりやすくするために、ネストされたリスト内包表記ではなく、冗長で明示的なバージョンを提示することにしました。この時点で

import tkinter as tk 

root = tk.Tk() 

variables = [] 
for i in range(3): 
    row = [] 
    for j in range(4): 
     variable = tk.StringVar() 
     row.append(variable)  
    variables.append(row) 

entries = [] 
for i in range(3): 
    row = [] 
    for j in range(4): 
     entry = tk.Entry(root, textvariable=variables[i][j]) 
     entry.grid(row=i, column=j) 
     row.append(entry) 
    entries.append(row) 

、我々はroot.mainloop()を呼び出して、あなたが生成されるようなエントリの同じグリッドを観察することができました。

ここで、get_values関数を定義しましょう。これは、エントリの入力を取得するのに役立ちます。 tkinter.Variableインスタンスがラップする値は、tkinter.Variable.getメソッドを通じてアクセスできます。

button = tk.Button(root, text="Print values", command=lambda: print(get_values())) 
button.grid(row=3, column=0, columnspan=4) 

、のroot.mainloop()を呼び出し、そして何が起こるか見てみましょう:

def get_values(): 
    values = [] 
    for j in range(4): 
     column = [] 
     for i in range(3): 
      column.append(entries[i][j].get()) 
     values.append(column) 

    return values 

最後に、私たちは現在の値を出力することを可能にするために、のボタンを作成してみましょう。 我々はPrint valuesボタンで、エントリの行列があります。

entries matrix

さて、いくつかのテキストとはPrint valuesヒット我々の入力とします。ここでは

Inputing values

がコンソールに出てくるものです:

[['hello', '', ''], ['', 'stuff', ''], ['', '', 'blah'], ['foo', '', '']] 

いつでも、ボタンを押すと、get_values関数は入力行列の現在の内容を返します。 私が言ったように、それは自動的に最新の状態に保たれるので、バインディングについて心配する必要はありません。 明白な利点は、ユーザーが入力を特定の順序で入力する必要がなく、タブを押して項目を切り替えることが強制されないことです。


編集

今、あなたは4列目にcolumn 2column 3の結果を表示したいです。 すでにエントリ変数を扱っているので、テキストを編集するのはかなり直接的です。 tk.Variable.traceメソッドを使用して、編集中のエントリのイベントを追跡するだけです。 まず、2つのソースセルの変数とターゲットセルの変数をパラメータとするbuild_callback関数を定義します。

def build_trace(source1, source2, target): 
    def callback(*_): 
     value1 = source1.get() 
     value2 = source2.get() 
     try: 
      value1 = float(value1) 
      value2 = float(value2) 
      target.set(value1*value2) 
     except: 
      target.set("") 

    return callback 

これは、二つのソースセルの値を取得するコールバックを作成する浮動小数点数に変換し、ターゲットの変数にそれらを書き込もう。 Tkinterの変数は、ウィジェットが変数を提供されている場合、後者への書き込みアクセスは前者を視覚的に変更するようなものです。 したがって、target.set(value1*value2)は、target変数の内部値を設定するだけでなく、新しい値を表示する関連エントリを作成します。

ここで、セルの1つが変更されたときはいつでも、正しいコールバックを呼び出すようにtkinterに指示する必要があります。 これは非常に簡単ですが、私たちはインデックスに注意する必要があります。

for i in range(3): 
    variables[i][1].trace(
     'w', 
     build_trace(variables[i][1], variables[i][2], variables[i][3])) 
    variables[i][2].trace(
     'w', 
     build_trace(variables[i][1], variables[i][2], variables[i][3])) 

だから、これは何を意味するのでしょうか? これは、variables[i][1]が書き込まれると('w')、build_trace(variables[i][1], variables[i][2], variables[i][3])のコールバックを実行する必要があることをtkinterに通知します。 build_trace関数が呼び出され、その結果が第2引数として渡されます。 この結果は内部のcallback関数です。 コールバックはいくつかの引数を指定して呼び出されるので、実際には気にしません。callback(*_)を定義して吸収します。これは基本的には「すべての引数をとり、_、つまりゴミ箱に入れる」という意味です。

これで、2番目または3番目の列を変更すると、4番目の列が変更されます。


自己宣伝のビットが、私はそれは読む価値だと思う:

+0

詳細な説明をありがとうございます。このシナリオでは完全に機能します。私を正しい方向に導いてくれてありがとう。 – Sundararajan

+0

列2の列3の計算を列4に表示したいのですが?それが私がこの方法を試した理由です。これに代わるものはありますか? – Sundararajan

+0

@Sundararajan私の編集内容を確認してください。リンク先の投稿も –

関連する問題