2016-05-24 4 views
1

В настоящее время у меня есть несколько валидаций для разных виджета ввода, и пока все команды настроены одинаково, выполняется только проверка для второй записи. Есть ли причина, почему другие нет? Вот часть моего кода дело с записями:Валидация для виджета ввода не ведет себя так, как ожидалось

import tkinter 
from tkinter import * 
import math 
from tkinter import messagebox 


class MyClass(tkinter.Frame): 
    def __init__(self, *args, **kwargs): 
     tkinter.Frame.__init__(self, *args, **kwargs) 

     #Setting up frame and widgets 
     vcmd1 = (self.register(self.__vcmd1), '%P', '%S') 
     vcmd2 = (self.register(self.__vcmd2), '%P') 
     vcmd3 = (self.register(self.__vcmd3), '%P', '%S') 

     self.v = IntVar() 
     self.v.set(1) 

     label_det = Label(self,text="Choose Detector") 
     self.mcp0 = Radiobutton(self, text="MCP-0",variable=self.v,value=1,command=self.selected) 
     self.mcp6 = Radiobutton(self, text="MCP-6",variable=self.v,value=2,command=self.selected) 
     self.mpet = Radiobutton(self,text="MCP-MPET",variable=self.v,value=3,command=self.selected) 

     label_det.grid(row=0, column=0, columnspan=2) 
     self.mcp0.grid(row=1,columnspan=2) 
     self.mcp6.grid(row=2,columnspan=2) 
     self.mpet.grid(row=3,columnspan=2) 

     label_iso = Label(self,text="Isotope A, Element (ex: 133,Cs)") 
     label_vol = Label(self, text="Beam Energy (eV)") 
     label_range = Label(self, text="Charge Range (ex:1,12)") 

     label_iso.grid(row=4, column=0, sticky=E) 
     label_vol.grid(row=5, column=0, sticky=E) 
     label_range.grid(row=6, column=0, sticky=E) 

     self.entry1 = tkinter.Entry(self, validate="key", validatecommand=vcmd1) 
     self.entry2 = tkinter.Entry(self, validate="key", validatecommand=vcmd2) 
     self.entry3 = tkinter.Entry(self, validate="key", validatecommand=vcmd3) 

     self.entry1.grid(row=4, column=1) 
     self.entry2.grid(row=5, column=1) 
     self.entry3.grid(row=6, column=1) 

    def __vcmd1(self, P, S): 
     validString = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM,1234567890' 
     if not S in validString: 
      messagebox.showinfo("Error", "Not valid") 
      return False 
     if "," in P: 
      messagebox.showinfo("Good", "Contain comma") 
      if len(P.split(",")) > 2: 
       messagebox.showinfo("Error", "Expected Form: ex. 133,Cs") 
       return False 
     else: 
      return True 

    def __vcmd2(self, P): 
     if P == '': 
      return True 
     try: 
      float(P) 
      return True 
     except ValueError: 
      messagebox.showinfo("Error", "Entry must be a float or integer") 
      return False 


    def __vcmd3(self, P, S): 
     if "," in P: 
      if len(P.split(",")) > 2: 
       messagebox.showinfo("Error", "Contain multiple commas") 
       return False 
      a = P.split(",")[0] 
      b = P.split(",")[1] 
      if a != '' and b != '': 
       try: 
        int(a) 
        int(b) 
       except ValueError: 
        messagebox.showinfo("Error", "Expected form: ex. 1,12") 
        return False 
     else: 
      return True 

    def selected(self): 
     if self.v.get() == 1: 
      self.x = 8.0 
     elif self.v.get() == 2: 
      self.x = 3.0 
     else: 
      self.x = 9.2 
     return self.x 

class TimeGenerator: 

    def __init__(self,master): 

     self.frame = MyClass(master) 
     self.frame.grid(columnspan=2) 

     self.text = Text(root) 
     self.iso = self.frame.entry1 
     self.vol = self.frame.entry2 
     self.r = self.frame.entry3 

     button = Button(root, text='Time Range', command=self.calculateTime) 
     button.grid(row=3, columnspan=2) 

    def calculateTime(self): 
     self.text.delete(1.0, END) 

     dict = {'h': 1, 'he': 2, 'li': 3, 'be': 4, 'b': 5, 'c': 6, 'n': 7, 'o': 8, 'f': 9, 'ne': 10, 
      'na': 11, 'mg': 12, 'al': 13, 'si': 14, 'p': 15, 's': 16, 'cl': 17, 'ar': 18, 
      'k': 19, 'ca': 20, 'sc': 21, 'ti': 22, 'v': 23, 'cr': 24, 'mn': 25, 'fe': 26, 'co': 27, 'ni': 28, 
      'cu': 29, 'zn': 30, 
      'ga': 31, 'ge': 31, 'as': 33, 'se': 34, 'br': 35, 'kr': 36, 'rb': 37, 'sr': 38, 'y': 39, 
      'zr': 40, 'nb': 41, 'mo': 42, 'tc': 43, 'ru': 44, 'rh': 45, 'pd': 46, 'ag': 47, 'cd': 48, 
      'in': 49, 'sn': 50, 'sb': 51, 'te': 52, 'i': 53, 'xe': 54, 'cs': 55, 'ba': 56, 
      'la': 57, 'ce': 58, 'pr': 59, 'nd': 60, 'pm': 61, 'sm': 62, 'eu': 63, 'gd': 64, 'tb': 65, 'dy': 66, 
      'ho': 67, 'er': 68, 'tm': 69, 'yb': 70, 'lu': 71, 
      'hf': 72, 'ta': 73, 'w': 74, 're': 75, 'os': 76, 'ir': 77, 'pt': 78, 'au': 79, 'hg': 80, 'tl': 81, 
      'pb': 82, 'bi': 83, 'po': 84, 'at': 85, 'rn': 86, 
      'fr': 87, 'ra': 88, 'ac': 89, 'th': 90, 'pa': 91, 'u': 92, 'np': 93, 'pu': 94, 'am': 95, 'cm': 96, 
      'bk': 97, 'cf': 98, 'es': 99, 'fm': 100, 'md': 101, 'no': 102, 'lr': 103, 
      'rf': 104, 'db': 105, 'sg': 106, 'bh': 107, 'hs': 108, 'mt': 109, 'ds': 110, 'rg': 111, 'cn': 112, 
      'uut': 113, 'fl': 114, 'uup': 115, 'lv': 116, 'uus': 117, 'uuo': 118} 

     if self.r.get() == "" or self.iso.get() == "" or self.vol.get() == "": 
      messagebox.showinfo("Error", "No field can be empty") 
      return None 

     r = self.r.get().replace(" ", "") 
     tup = tuple(int(x) for x in r.split(",")) 

     iso = self.iso.get().replace(" ", "") 
     list = [] 
     for e in iso.split(","): 
      list.append(e) 

     if (dict[list[1].lower()] < tup[0]) or (dict[list[1].lower()] < tup[1]): 
      messagebox.showinfo("Error", "Change state range does not exist for given element") 
      return None 

     f = open("/Users/LazyLinh/PycharmProjects/TimeGenGUI/mass.mas12.txt", "r") 
     i = 0 
     while (i < 40): 
      header = f.readline() 
      i += 1 
     self.mass = 0 

     #iterate through text file 

     for line in f: 
      line = line.strip() 
      columns = line.split() 
      if (list[0] == columns[3]): 
       if (list[1].lower() == columns[4].lower()): 
        if (len(columns) == 16): 
         self.mass = float(columns[13].replace("#","")) + float(columns[14].replace("#",""))/10e6 
        else: 
         self.mass = float(columns[12].replace("#","")) + float(columns[13].replace("#",""))/10e6 

     #Calculation 

     list = [] 
     for q in range(tup[0], tup[1] + 1): 
      y = (self.frame.selected() * math.sqrt(self.mass * 1.6605402e-27/(2 * q *1.6022e-19 * float(self.vol.get())))) * 10e6 
      list.append(y) 
     i = tup[0] 

     #inserting to text widget 
     for time in list: 
      self.text.insert("end", "%d: %s\n" % (i, time)) 
      i = i + 1 
     self.text.grid() 

     self.iso = self.frame.entry1 
     self.vol = self.frame.entry2 
     self.r = self.frame.entry3 


root = Tk() 
b = TimeGenerator(root) 
root.mainloop() 

наблюдаются ошибки включают возможность добавлять символы не из validString для записи 1, или быть в состоянии добавить несколько «» для записи 3 ...

EDIT: Я включил свой полный код и то, что я пробовал

+0

Ваш код, похоже, работает на меня. Я не могу войти в "!" или «@» в первом поле, а ошибки появляются, когда я вводю запятые в третьем поле. Вы пытались добавить команды отладки, чтобы точно определить, какой оператор возврата используется для каждого ввода? –

+0

@BryanOakley Для первой записи появится msgbox «Содержит запятую», но не «Недействительный» или «Ожидаемая форма», даже если я ввешу недопустимый символ или несколько запятых. И для третьей записи «Содержит несколько запятые "не отображаются, даже если я использовал несколько запятых, что похоже на 1-ю запись ... –

+0

Единственная проблема - логическая проблема. В коде нет ничего технически неправильно. Например, если вы вводите недопустимый символ в в первом поле вы даже не пытаетесь показать сообщение. Вы возвращаете 'False', что заставляет tkinter отклонять редактирование. Если вы хотите, чтобы появилось сообщение, вы должны явно сделать это. –

ответ

1

Код технически работает, хотя у вас есть логические ошибки, которые, возможно, мешают ему работать так, как вы ожидаете.

Для проверки работоспособности, это должно вернуть либо True, либо False. Любая другая действительная функция отключит проверку. В ваших командах есть пути через код, который не возвращает True или False, в результате чего проверка проверки будет отключена.

Например, в _vcmd 1, если P содержит запятую, но выражение len(P.split(",")) > 2 является False, вы в конечном итоге возвращение None который отменяет любые будущие проверки.

Аналогичным образом, в _vcmd3 у вас есть путь через код, который возвращает None. Спросите себя, что произойдет, когда вы войдете в «4». Функция возвращает None, которая, опять же, отменяет будущую проверку.

Итог: ваши функции должны всегда возвращение либо True или False, или проверка будет отключена.

+0

Я определенно пропустил эту логическую ошибку. Большое вам спасибо за помощь! –

Смежные вопросы