2017-07-10 11 views
-1

私はtkinterを使ってGUIを作っています。tkinterコードに検証を追加する

私のコードのフレーム2には、エントリウィジェットがあります。私は数字だけを有効にしたい。文字ウィジェット、特殊文字、記号、スペースなどがボタンを押した後に入力ウィジェットに入力された場合、エラーウィジェットをテキストウィジェットに印刷するにはどうすればよいですか? PythonではWhile Trueを使用しましたが、これがtkinterで使用できるかどうか、またコード内で検証を行う場所であるかどうかはわかりません。

私のコードは以下の通りです。

import tkinter as tk    # python 3 
from tkinter import font as tkfont # python 3 
from tkinter import StringVar 
import pandas as pd 
from tkinter import ttk 

df = {"Option B":[0,10,25,100,120,140,160,200,500,800,1200,1700,2000], 
    "Option A":[0,0,15,90,110,130,150,190,490,790,1190,1690,1990]} 
price_options = pd.DataFrame(df,index=["0", 
         "1 - 50", 
         "51 to 75", 
         "76 to 90", 
         "91 to 100", 
         "101 to 110", 
         "111 to 130", 
         "131 to 150", 
         "151 to 170", 
         "171 to 190", 
         "191 to 225", 
         "226 to 255", 
         "Over 255"]) 


class My_GUI(tk.Tk): 

def __init__(self, *args, **kwargs): 
    tk.Tk.__init__(self, *args, **kwargs) 

    self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic") 

    # the container is where we'll stack a bunch of frames 
    # on top of each other, then the one we want visible 
    # will be raised above the others 
    container = tk.Frame(self) 
    container.pack(side="top", fill="both", expand=True) 
    container.grid_rowconfigure(0, weight=1) 
    container.grid_columnconfigure(0, weight=1) 

    self.frames = {} 
    for F in (StartPage, Page2, Page3): 
     page_name = F.__name__ 
     frame = F(parent=container, controller=self) 
     self.frames[page_name] = frame 

     # put all of the pages in the same location; 
     # the one on the top of the stacking order 
     # will be the one that is visible. 
     frame.grid(row=0, column=0, sticky="nsew") 

    self.show_frame("StartPage") 

def show_frame(self, page_name): 
    #Show a frame for the given page name 
    frame = self.frames[page_name] 
    frame.tkraise() 

class StartPage(tk.Frame): 

def __init__(self, parent, controller): 
    tk.Frame.__init__(self, parent) 
    self.controller = controller 
    label = tk.Label(self, text="Welcome.....\nCheck how much it will cost......\n", font=controller.title_font) 
    label.pack(side="top", fill="x", pady=10) 

    button1 = tk.Button(self, text="Item A", 
         command=lambda: controller.show_frame("Page2")) 
    button2 = tk.Button(self, text="Item B", 
         command=lambda: controller.show_frame("Page3")) 
    button1.pack() 
    button2.pack() 

class Page2(tk.Frame): 

def __init__(self, parent, controller): 
    tk.Frame.__init__(self, parent) 
    self.controller = controller 
    label = tk.Label(self, text="Select from the options below", font=controller.title_font) 
    label.pack(side="top", fill="x", pady=10) 

    global df 
    tk.Label(self, text='Select option:').pack() 
    self.options = ttk.Combobox(self, values=list(price_options.columns)) 
    self.options.pack() 




    label = tk.Label(self, text="How much does the item weigh?", font=controller.title_font) 
    label.pack() 

    self.weight_entry = tk.Entry(self) 
    self.weight_entry.pack() 

    tk.Button(self, text='Click here to display price', command=self.show_option).pack() 

    self.text = tk.Text(self) 
    self.text.pack() 

    tk.Button(self, text="Restart", 
       command=lambda: controller.show_frame("StartPage")).pack() 

def show_option(self): 
    identifier = self.options.get() # get option 
    weight_id = int(self.weight_entry.get()) 
    self.text.delete(1.0, tk.END) # empty widget to print new text 
    #self.text.insert(tk.END, str(price_options[identifier])) 


    if identifier == "Option B": 

     if weight_id == 0: self.text.insert(tk.END, str(price_options.iloc[:1,1:2])) 
     elif weight_id >= 1 and weight_id <= 50: self.text.insert(tk.END, str(price_options.iloc[1:2,1:2])) 
     elif weight_id >= 51 and weight_id <= 75 : self.text.insert(tk.END, str(price_options.iloc[2:3,1:2])) 

    elif identifier == "Option A": 
     if weight_id == 0: self.text.insert(tk.END, str(price_options.iloc[:1,:1])) 
     elif weight_id >= 1 and weight_id <= 50 : self.text.insert(tk.END, str(price_options.iloc[1:2,:1])) 
     elif weight_id >= 51 and weight_id <= 75 : self.text.insert(tk.END, str(price_options.iloc[2:3,:1])) 


class Page3(tk.Frame): 

def __init__(self, parent, controller): 
    tk.Frame.__init__(self, parent) 
    self.controller = controller 
    label = tk.Label(self, text="Some text here...", font=controller.title_font) 
    label.pack(side="top", fill="x", pady=10) 
    button = tk.Button(self, text="Go to the start page", 
         command=lambda: controller.show_frame("StartPage")) 
    button.pack()   

if __name__ == "__main__": 
app = My_GUI() 
app.mainloop() 
+0

あなたのインデントを台無しにされ、かつ完全であること、あなたはあまりにも多くのコードを掲載しました:意味、ユーザーが文字やエントリに、他の非数値文字を入力しようとすると、彼らは表示されません質問されている質問とは無関係です。 –

答えて

-1

あなたは、機能int()は自動的に外側のスペース(エラーが数字と任意の数字ではない文字間のスペースのためにスローされます)

def show_option(self): 
     identifier = self.options.get() # get option 
     try: 
      weight_id = int(self.weight_entry.get()) 
      self.text.delete(1.0, tk.END) # empty widget to print new text 
      if identifier == "Option B": 

       if weight_id == 0: self.text.insert(tk.END, str(price_options.iloc[:1,1:2])) 
       elif weight_id >= 1 and weight_id <= 50: self.text.insert(tk.END, str(price_options.iloc[1:2,1:2])) 
       elif weight_id >= 51 and weight_id <= 75 : self.text.insert(tk.END, str(price_options.iloc[2:3,1:2])) 

      elif identifier == "Option A": 
       if weight_id == 0: self.text.insert(tk.END, str(price_options.iloc[:1,:1])) 
       elif weight_id >= 1 and weight_id <= 50 : self.text.insert(tk.END, str(price_options.iloc[1:2,:1])) 
       elif weight_id >= 51 and weight_id <= 75 : self.text.insert(tk.END, str(price_options.iloc[2:3,:1]))    
     except: 
      self.text.delete(1.0, tk.END) 
      self.text.insert(1.0, 'Wrong input') 
+0

提案していただきありがとうございます。また動作します。 – bagpuss

1

エントリを取り除き除いて/試しに入力を包むことができウィジェットには、「有効な」入力のみをエントリに追加できるようにする検証オプションがあります。

class Page2(tk.Frame): 

    def __init__(self, parent, controller): 
     ... 

     vcmd = (self.register(self.onValidate), '%S') 
     self.weight_entry = tk.Entry(self, validate='key', vcmd=vcmd) 
     self.weight_entry.pack() 

     ... 

    def onValidate(self, S): 
     if S in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']: 
      return True 
     else: 
      # output warning message here 
      return False 

    def show_option(self): 
     ... 
+0

ありがとうございました。完璧に動作します。私は自分のコードでこれを使用します。 – bagpuss

関連する問題