2016-01-04 210 views
1

我正在处理的程序允许用户输入文本并检查它是否是回文。输入顺序为order(),用testPalindrome(orderedText)进行测试,然后使用showResult(Palindrome)显示结果。当谈到保存回文时,我的问题就出现了。如果用户被验证为回文,用户应该能够保存输入。我认为这是有道理的,如果保存按钮被禁用,直到一个输入已被测试为真。所以我在showResult(Palindrome)中放置了“saveButton.config(state ='normal')”,但这不起作用。该错误说“全局名称”saveButton'未定义“,我可以明白为什么。但是,我无法做到正确。我想知道是否有可能通过对这一行文本的补充来解决这个问题,或者如果我必须做出更彻底的修改。 (我试过例如把“saveButton”到一个全局变量,如“inputEntry”,但不管是什么原因,我不能得到这工作的。)更改Tkinter中的按钮状态

import Tkinter 

    root = Tkinter.Tk() 
    infoLabel = Tkinter.Label(root, text = 'Enter a text and check if it is a palindrome.', height = 12, width = 64, bg = 'green') 
    inputEntry = Tkinter.Entry(root, width = 64) 

    def main(): 
     window() 
     Tkinter.mainloop() 

    def window(): 
     root.title('Palindrome detector') 
     root.geometry('534x285+500+250') 
     infoLabel.grid(row = 0, rowspan = 1, column = 0, columnspan = 4, pady = 8, padx = 8) 
     inputEntry.insert(0, 'Enter text...') 
     inputEntry.grid(row = 1, rowspan = 1, column = 0, columnspan = 4, padx = 4) 
     verifyButton = Tkinter.Button(root, text = 'Verify', width = 7, command = order).grid(row = 2, column = 0, pady = 10) 
     saveButton = Tkinter.Button(root, text = 'Save', state = 'disabled', width = 7, command = save).grid(row = 2, column = 3) 

    def order(): 
     Text_input = inputEntry.get() 
     orderedText = Text_input.replace(" ", "") 
     orderedText = orderedText.lower() 
     orderedText = filter(str.isalnum, orderedText) 
     if any(char.isalpha() or char.isdigit() for char in orderedText): 
      testPalindrome(orderedText) 
     else: 
      infoLabel.config(text = 'The input must contain at least one alphanumeric character.', bg = 'red') 

    def testPalindrome(orderedText): 
     Palindrome = True 
     i = 0 
     for char in orderedText: 
      if orderedText[i] == orderedText[-(i+1)]: 
       Palindrome = True 
       i += 1 
      else: 
       Palindrome = False 
       break 
     showResult(Palindrome) 

    def showResult(Palindrome): 
     if Palindrome == True: 
      infoLabel.config(text = 'Yes! "' + str(inputEntry.get()) + '" is a palindrome!', bg = 'green') 
      saveButton.config(state = 'normal') 
     else: 
      infoLabel.config(text = 'No! "' + str(inputEntry.get()) + '" is not a palindrome!', bg = 'red') 
      saveButton.config(state = 'disabled') 

    def save(): 
     savePalindrome = inputEntry.get() 
     palindromes_file = open("Palindromes.txt", "a") 
     palindromes_file.write(savePalindrome + "\n") 
     palindromes_file.close() 
     infoLabel.config(text = '"' + str(savePalindrome) + '" has been saved to file.', bg = 'green') 
     saveButton.config(state = 'disabled') 

    if __name__ == '__main__': 
     main() 

编辑:阅读的答案后,我跟着教科书,并试图用班级来重写整个事物。当然,可能会有任何数量的缺陷。我现在关心的是“NameError:全球名称'testPalindrome'未定义”。错误(第7行)顺序(自我)。我看不出为什么这条线和order(self)和testPalindrome(self)之间的“桥梁”突然出现问题?

import Tkinter 
    import tkMessageBox 

    root = Tkinter.Tk() 

    class MyGUI: 
     def __init__(self, master): 
      self.master = master 
      master.title('Palindrome detector') 
      master.geometry('534x285+500+250') 
      self.infoLabel = Tkinter.Label(self.master, text = 'Enter a text and check if it is a palindrome.', height = 12, width = 64, bg = 'green') 
      self.inputEntry = Tkinter.Entry(self.master, width = 64) 
      self.infoLabel.grid(row = 0, rowspan = 1, column = 0, columnspan = 4, pady = 8, padx = 8) 
      self.inputEntry.insert(0, 'Enter text...') 
      self.inputEntry.grid(row = 1, rowspan = 1, column = 0, columnspan = 4, padx = 4) 
      self.verifyButton = Tkinter.Button(self.master, text = 'Verify', width = 7, command = self.order) 
      self.verifyButton.grid(row = 2, column = 0, pady = 10) 
      self.saveButton = Tkinter.Button(self.master, text = 'Save', state = 'disabled', width = 7, command = self.save) 
      self.saveButton.grid(row = 2, column = 3) 

     def order(self): 
      self.Text_input = self.inputEntry.get() 
      self.orderedText = self.Text_input.replace(" ", "") 
      self.orderedText = self.orderedText.lower() 
      self.orderedText = filter(str.isalnum, self.orderedText) 
      if any(char.isalpha() or char.isdigit() for char in self.orderedText): 
       testPalindrome(self) 
      else: 
       self.infoLabel.config(text = 'The input must contain at least one alphanumeric character.', bg = 'red') 

     def testPalindrome(self): 
      self.Palindrome = True 
      i = 0 
      for char in self.orderedText: 
       if self.orderedText[i] == self.orderedText[-(i+1)]: 
        self.Palindrome = True 
        i += 1 
       else: 
        self.Palindrome = False 
        break 
      showResult(self) 

     def showResult(self): 
      if self.Palindrome == True: 
       self.infoLabel.config(text = 'Yes! "' + str(self.inputEntry.get()) + '" is a palindrome!', bg = 'green') 
       self.saveButton.config(state = 'normal') 
      else: 
       self.infoLabel.config(text = 'No! "' + str(self.inputEntry.get()) + '" is not a palindrome!', bg = 'red') 
       self.saveButton.config(state = 'disabled') 

     def save(self): 
      self.savePalindrome = self.inputEntry.get() 
      self.palindromes_file = open("Palindromes.txt", "a") 
      self.palindromes_file.write(self.savePalindrome + "\n") 
      self.palindromes_file.close() 
      self.infoLabel.config(text = '"' + str(self.savePalindrome) + '" has been saved to file.', bg = 'green') 
      self.saveButton.config(state = 'disabled') 

    my_gui = MyGUI(root) 
    Tkinter.mainloop() 
+2

这并不能完全回答你的问题,但你不应该'grid'或'pack'或'place'一个小部件,并将其分配给同一行上的变量。有关更多信息,请参见[Tkinter:AttributeError:NoneType对象没有获取属性](http://stackoverflow.com/q/1101750/953482)。 – Kevin

+0

顺便说一句:总是把完整的错误信息,而不是描述它。 – furas

回答

1

您在功能创建saveButton所以它是局部变量,它不是在其他功能avaliable。您可以使用global saveButton中的window()使此变量全局。

def window(): 
    global saveButton 

    # .... 

    saveButton = Tkinter.Button(...) 
    saveButton.grid(...) 

-

正如凯文已经说过:

此行

saveButton = Tkinter.Button(...).grid(...) 

分配NonesaveButton因为grid()总是返回None

使用

saveButton = Tkinter.Button(...) 
saveButton.grid(...) 

Tkinter.Button(...).grid(...) 

如果你不需要saveButton变量。

+0

“全球saveButton”工作,但我认为全局变量有点皱眉了?有没有其他方法可以调查? – VillaRava

+0

你可以使用面向对象编程(OOP)并创建具有所有功能的类并使用'self.'而不是'global'。 – furas

0

只需在您的验证功能中打电话,因为您想每次都是自动保存时,它是一个回文。您可以将该值传递给该函数,而不是第二次获取该值。

def testPalindrome(orderedText): 
    ## change to False so an empty string will not 
    ## register as True 
    Palindrome = False 
    i = 0 
    for char in orderedText: 
     if orderedText[i] == orderedText[-(i+1)]: 
      Palindrome = True 
      i += 1 
     else: 
      Palindrome = False 
      break 
    showResult(Palindrome) 
    if Palindrome: 
     save(orderedText) 

下一步学习类,因为它解决了这些问题。网络上的许多教程之一http://python-textbok.readthedocs.org/en/latest/Introduction_to_GUI_Programming.html要使按钮成为全局,请将其放入全局名称空间(如inputEntry)。

root = Tkinter.Tk() 
infoLabel = Tkinter.Label(root, text = 'Enter a text and check if it is a palindrome.', height = 12, width = 64, bg = 'green') 
inputEntry = Tkinter.Entry(root, width = 64) 

saveButton = Tkinter.Button(root, text = 'Save', state = 'disabled', width = 7, command = save) 
saveButton.grid(row = 2, column = 3) 
+0

以这种方式使saveButton全局使我“NameError:name'保存'未定义”。 – VillaRava

+0

函数必须在使用之前进行声明,因此解决问题的方法是,如果尝试不同的操作,则可以计算出该问题。再一次,对于未来的尝试,类结构没有这些问题,所以大多数人都忽略了这个线程,因为你正在创建自己的,不必要的问题。 –