2017-10-21 9 views
1

私はSpinboxウィジェットに整数値を入力できるようにしたいと思っています。入力された値が整数でないか、スピンボックスの制限外の整数である場合、スピンボックスがフォーカスを失うとすぐに、スピンボックスのコンテンツの値をデフォルト値に戻す必要があります。tkinterのウィジェットの検証

例のコードでは、Spinboxのフォーカスを失うためにEntryウィジェットを使用します。

ユーザが新しい値を入力するためにSpinboxに戻った場合、そのエントリは検証されません。 Interactively validating Entry widget content in tkinterにMalcolmの発言があり、このコマンドがウィジェットの値を更新するとすぐにvalidatecommand=command機能がクリアされることを確認します。

Spinboxに入力された値を繰り返し有効にする方法はありますか?

from tkinter import * 


class GUI: 

    def __init__(self): 
     # root window of the whole program 
     self.root = Tk() 
     self.root.title('Validate Spinbox') 

     # registering validate and invalid commands 
     validate_cmd = (self.root.register(self.validate), '%P') 
     invalid_cmd = (self.root.register(self.invalid)) 

     # creating a Label 
     items_lbl = Label(self.root, text="# of items (5-10):") 
     items_lbl.grid(row=0, column=0) 

     # creating a Spinbox widget 
     self.items_var = StringVar() 
     self.items_var.set(7) 
     items_count = Spinbox(self.root, textvariable=self.items_var, 
           from_=5, to=10, width=4, validate='focusout', 
           validatecommand=validate_cmd, 
           invalidcommand=invalid_cmd) 
     items_count.grid(row=0, column=1) 

     # creating an Entry widget 
     self.entry_var = StringVar() 
     self.entry_var.set("Input some text here") 
     text_entry = Entry(self.root, textvariable=self.entry_var) 
     text_entry.grid(row=1, column=0) 

    def validate(self, entry): 
     try: 
      value = int(entry) 
      valid = value in range(5, 11) 
     except ValueError: 
      valid = False 
     if not valid: 
      self.root.bell() 
     return valid 

    def invalid(self): 
     self.items_var.set(7) 


if __name__ == '__main__': 
    main_window = GUI() 
    mainloop() 
+1

validatecommand'はOKまま '、それは'だあなたはSpinboxインスタンスがselfで、属性を作成する必要があり

validate'パラメータがリセットされる 'focusout'イベントにバインドされました – PRMoureu

+0

@PRMoureu:ありがとうございました! ** validate **パラメータをリセットしない方法はありますか?私がコードを修正することができれば、私はPythonに慣れていないので、私は大いに義務づけられます。 – nkana

答えて

1

私は(章検証の最後の段落で)ここに偉大な説明を見つける:あなたのvalidatecommand(またはinvalidcommand)は、直接または間接的にエントリを変更する場合

http://stupidpythonideas.blogspot.fr/2013/12/tkinter-validation.html

を(例えば、そのStringVarでsetを呼び出すことによって)、関数が返ったらすぐに検証は無効になります。 (これは、Tkが無限ループを検証して別のバリデーションをトリガするのを防ぐ方法です)。これを元に戻す必要があります(configを呼び出すことによって)。しかし、あなたは関数の中でそれを行うことはできません。なぜなら、関数が返ってから無効になるからです。

ただし、このトリックを使用するには、いくつかの変更を適用する必要があります。

self.items_count = Spinbox(self.root, textvariable=self.items_var, 
         from_=5, to=10, width=4, validate='focusout', 
         validatecommand=validate_cmd, 
         invalidcommand=invalid_cmd) 
self.items_count.grid(row=0, column=1) 

そしてあなたはvalidateメソッド内self.items_count.after_idle(...)を呼び出すことができます:

def validate(self, entry): 
    try: 
     value = int(entry) 
     valid = value in range(5, 11) 
    except ValueError: 
     valid = False 
    if not valid: 
     self.root.bell() 
     self.items_count.after_idle(lambda: self.items_count.config(validate='focusout')) 
    return valid 
+1

ありがとうございました!!!問題が解決しました!!!!!! – nkana

+0

助けてくれてうれしい、このブログの作者に感謝します。 – PRMoureu

関連する問題