2016-03-07 2 views
0

Я пытаюсь построить тест с использованием Tkinter и питона 2Tkinter ошибка UnboundLocalError: локальная переменная «флаг» ссылка Перед назначением

У меня возникли проблемы с поддержанием баллов. Кнопка подтверждения может быть нажата несколько раз, что увеличивает счетчик глобальных счетчиков. 1) У меня есть одна переменная флагов, которая позволяет отвечать только один раз и увеличивать глобальный счетчик только один раз. Можно ли отключить кнопку проверки правильности ответа? Но я заблуждаюсь.

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1489, in __call__ 
    return self.func(*args) 
    File "testtest.py", line 22, in validate 
    if(q=="4" and flag==0): 
UnboundLocalError: local variable 'flag' referenced before assignment 

Я читал другие ответы на эту проблему но если передать аргументы функции подтверждению он дает ошибку.

2) Есть ли способ реализовать викторину, поскольку она отобразит 1-й вопрос, и если ответ правильный, событие кнопки направит 2-й вопрос в отличие от моего кода. Он отображает все вопросы
Моего кода:

import Tkinter as tk 
import tkMessageBox 
count=0 

class Question(tk.Frame): 
    def __init__(self, *args, **kwargs): 
      tk.Frame.__init__(self, *args, **kwargs) 
    def show(self): 
      self.lift() 

class Question1(Question): 
    def __init__(self, *args, **kwargs): 
      Question.__init__(self, *args, **kwargs) 
      label = tk.Label(self, text="Question 1: What is 2^2") 
      label.pack(side="top", fill="both", expand=True) 
      entry = tk.Entry(self) 
      entry.pack(side="top", fill="both", expand=True) 
      def validate(event): 
       q=entry.get() 

       if(q=="4" and flag==0): 
        tkMessageBox.showinfo('Correct Answer', 'Proceed to next question') 
        global count 
        count=count+1 
        fp=open("scores.txt","a") 
        fp.write("\nScore after Question 1 :%d "%(count)) 
        flag=1 
       else: 
        tkMessageBox.showinfo('Wrong Answer', 'Try Again') 
        #flag=0 to avoid alternate event 

      button_1 = tk.Button(self, text="Validate") 
      flag=0 
      button_1.bind("<Button-1>", validate) 

      button_1.pack(side="top", fill="both", expand=True) 

class Question2(Question): 

    def __init__(self, *args, **kwargs): 
      Question.__init__(self, *args, **kwargs) 
      label = tk.Label(self, text="Question 1: What is 2^3") 
      label.pack(side="top", fill="both", expand=True) 
      entry = tk.Entry(self) 
      entry.pack(side="top", fill="both", expand=True) 

      def validate(event): 
       q=entry.get() 

       if(q=="8" and flag==0): 

        tkMessageBox.showinfo('Correct Answer', 'Proceed to next question') 
        global count 

        count=0 
        count=count+1 


        fp=open("scores.txt","a") 
        fp.write("\nScore after Question 2 :%d "%(count)) 
        flag=1 


       else: 
        tkMessageBox.showinfo('Wrong Answer', 'Try Again') 

      button_1 = tk.Button(self, text="Validate") 
      flag=0 
      button_1.bind("<Button-1>", validate) 
      button_1.pack(side="top", fill="both", expand=True) 


class MainView(tk.Frame): 
    def __init__(self, *args, **kwargs): 
      tk.Frame.__init__(self, *args, **kwargs) 
      p1 = Question1(self) 
      p2 = Question2(self) 

      buttonframe = tk.Frame(self) 
      container = tk.Frame(self) 
      buttonframe.pack(side="top", fill="x", expand=False) 
      container.pack(side="top", fill="both", expand=True) 

      p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1) 
      p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1) 


      b1 = tk.Button(buttonframe, text="Question 1", command=p1.lift) 
      b2 = tk.Button(buttonframe, text="Question 2", command=p2.lift) 


      b1.pack(side="left") 
      b2.pack(side="left") 


      p1.show() 

if __name__ == "__main__": 
    root = tk.Tk() 
    main = MainView(root) 
    main.pack(side="top", fill="both", expand=True) 
    root.wm_geometry("1080x720") 
    root.mainloop() 
+0

В отступе Python имеет решающее значение - это часть синтаксиса. Пожалуйста, отложите свой код должным образом (стандарт - 4 пробела на блок кода), чтобы мы могли правильно проанализировать ваш код. –

+0

@ Рогальский сейчас все в порядке? Я перепутал при копировании кода –

ответ

0

Если присвоить имя в функции, она становится локальным именем, даже если функция вложена в сфере с другими функциями, что обеспечивает определение. В Python 3 вы можете явно объявить nonlocal flag в верхней части своей функции validate, чтобы он работал на flag из вложенной области, но в Python 2 вы не можете; Для этой цели Python 2 имеет только global, который пропускает вложенную область и ищет flag в области верхнего уровня модуля; обычно плохая идея для подобных случаев.

Один из подходов заключается в использовании list, поэтому вы назначаете индекс, а не переписываете локальное имя.

class Question1(Question): 
    def __init__(self, *args, **kwargs): 
     Question.__init__(self, *args, **kwargs) 
     label = tk.Label(self, text="Question 1: What is 2^2") 
     label.pack(side="top", fill="both", expand=True) 
     entry = tk.Entry(self) 
     entry.pack(side="top", fill="both", expand=True) 
     flag = [0] # Use list over plain int so you can index 
     def validate(event): 
      q=entry.get() 

      if q == "4" and not flag[0]: # Test index of list 
       tkMessageBox.showinfo('Correct Answer', 'Proceed to next question') 
       global count 
       count=count+1 
       with open("scores.txt","a") as fp: 
        fp.write("\nScore after Question 1 :%d "%(count)) 
       flag[0] = 1 # Assign to index of list 
      else: 
       tkMessageBox.showinfo('Wrong Answer', 'Try Again') 
       flag[0] = 0 # Assign to index of list 

     button_1 = tk.Button(self, text="Validate") 
     button_1.bind("<Button-1>", validate) 

     button_1.pack(side="top", fill="both", expand=True) 

Вы должны были бы сделать аналогичные изменения в Question2, а также.

Примечание: Я также поменял вас на использование инструкции with для обработки файлов, поэтому файл закрыт и данные записываются на диск в предсказуемое время.

+0

Можно ли отключить кнопку подтверждения после правильного ответа? –

+0

@PariTosh: Я уверен, что это, хотя это выходит из-за темы для вашего вопроса. Предположительно, вы бы использовали вызов типа 'button_1.unbind'; Я не знаю «Tk» с головы, но большинство языков, управляемых событиями, которые предоставляют «bind», также предоставляют «unbind», «detach» или аналогичный метод. – ShadowRanger

+0

Я получаю эту ошибку: Traceback (последний звонок последний): Файл "testtest.py", строка 100, в основной = MainView (корень) Файл "testtest.py", строки 76, в __init__ р1 = Вопрос1 (само) Файл "testtest.py", строка 33, в __init__ флаг [0] = 0 IndexError: индекс назначение списка из диапазона –

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