2017-05-16 12 views
0

그래서 저는 나무 딸기 파이에서하고있는 작은 프로젝트에서이 GUI를 만들려고합니다. 기본적으로 상태 머신은 버튼 프레스를 기반으로 상태를 바꿉니다 (약간의 퀴즈처럼 상상해보십시오). 내가 모듈을 실행할 때 몇 가지 이유를 들어, 나는 말한다 오류 얻을 :이 오류 코드를 기반으로 인터넷의 주위에 많이 검색했습니다간단한 GUI 코드 Tkinter 콜백 오류 받기

Exception in Tkinter callback 
Traceback (most recent call last): 
File:"/usr/lib/python2.7/lib-tk/Tkinter.py", line 1535, in __call__ 
    return self.func(*args) 
File:"/usr/lib/python2.7/lib-tk/Tkinter.py", line 586, in callit 
    func(*args) 
File "/home/pi/Desktop/SafetyDoorknob.py", line 79, in safety_loop 
NameError: global name 'currentState' is not defined 

을,하지만 난 도움이되었습니다 아무것도 발견하지 않았습니다 . 저는 Python과 Tkinter를 처음 사용했습니다. (지난 주 안에) 여기있는 사람이 도움이 될지 알고 싶었습니다. 아래에 내 코드 사본이 있습니다. 사전에 어떤 도움을 주셔서 감사합니다 그리고 난 아직도 물건

import Tkinter as tk 
from PIL import Image, ImageTk 
import requests 
import time 
import RPi.GPIO as GPIO 
import random 
import os 
import sys 

Button_A = 29 # The GPIO pin the button is attached to 
Button_B = 31 # The GPIO pin the button is attached to 
Button_C = 33 # The GPIO pin the button is attached to 
Button_D = 35 # The GPIO pin the button is attached to 
Button_Confirm = 37 # The GPIO pin the button is attached to 

Relay_Contact = 38 

#//////Setting up the pinmodes/////// 
GPIO.setmode(GPIO.BCM) #Defines what the numbering scheme is for the pins 
GPIO.setup(Button_A, GPIO.IN, pull_up_down=GPIO.PUD_UP) #Setting the button as an input and turning on some Pull-up resistors 
GPIO.setup(Button_B, GPIO.IN, pull_up_down=GPIO.PUD_UP) 
GPIO.setup(Button_C, GPIO.IN, pull_up_down=GPIO.PUD_UP) 
GPIO.setup(Button_D, GPIO.IN, pull_up_down=GPIO.PUD_UP) 
GPIO.setup(Button_Confirm, GPIO.IN,pull_up_down=GPIO.PUD_UP) 

GPIO.setup(Relay_Contact, GPIO.OUT) #Making the Relay contact an output. 

global usableQuestions 
global currentState 
global stateStartTime 
global picPath 
global correctAnswer 
global allAnswers 

mainFolderPath = "/home/pi/SafetyDoorknob/AllQuestions" #All Level Folders will be in SafetyDoorknob 
answersPath = "/home/pi/SafetyDoorknob/DoorknobAnswers.txt" 
picPath = "/home/pi/SafetyDoorknob/HomeScreen.jpg" 
answers_file = open(answersPath,'r') 
allAnswers = answers_file.readline().split(",") #Load all answers into String Array 
usableQuestions = os.listdir(mainFolderPath) 


root = tk.Tk() 
root.geometry("800x480") 
root.configure(background = 'black') 
root.wm_attributes('-type','splash') 

def buttonPressToAnswer(): 
    currentAnswer = "" 

    if GPIO.input(Button_A) == 0: 
     time.sleep(0.02) 
     currentAnswer = "A" 
    elif GPIO.input(Button_B) == 0: 
     time.sleep(0.02) 
     currentAnswer = "B" 
    elif GPIO.input(Button_C) == 0: 
     time.sleep(0.02) 
     currentAnswer = "C" 
    elif GPIO.input(Button_D) == 0: 
     time.sleep(0.02) 
     currentAnswer = "D" 

    return currentAnswer 


def get_State_Time(): 

    stateTime = time.time() - stateStartTime 
    return int(round(stateTime)) 

def setState(newState): 
    currentState = newState 
    stateStartTime = time.time() 

def safety_loop(): 

    if currentState == 0: #Startup State 
     picPath = "/home/pi/SafetyDoorknob/HomeScreen.jpg" 

     if GPIO.input(Button_Confirm) == 0: 
      time.sleep(0.02) 
      while GPIO.input(Button_Confirm) == 0: 
       pass 
      setState(1) 
      picPath = pick_rand_img() 
     root.after(10,safety_loop) 

    elif currentState == 1: #Question 1 State 
     while get_State_Time() <= 120: 
      if buttonPressToAnswer() == correctAnswer: 
       break 
      else: 
       pass 
     if get_State_Time() <=120: 
      setState(2) 
      picPath = pick_rand_img() 
     else: 
      setState(0) 

     root.after(10,safety_loop) 

    elif currentState == 2: #Question 2 State 
     while get_State_Time() <= 120: 
      if buttonPressToAnswer() == correctAnswer: 
       break 
      else: 
       pass 
     if get_State_Time() <=120: 
      setState(3) 
      picPath = pick_rand_img() 
     else: 
      setState(0) 

     root.after(10,safety_loop) 

    elif currentState == 3: #Question 3 State 
     while get_State_Time() <= 120: 
      if buttonPressToAnswer() == correctAnswer: 
       break 
      else: 
       pass 
     if get_State_Time() <=120: 
      setState(4) 
      picPath = pick_rand_img() 
     else: 
      setState(0) 

     root.after(10,safety_loop) 

    elif currentState == 4: #Door Open State 

     GPIO.output(Relay_Contact,1) 
     time.sleep(60) 
     GPIO.output(Relay_Contact,0) 


def pick_rand_img(): 

    if len(usableQuestions) == 0: 

     usableQuestions = os.listdir(mainFolderPath) 


    randomIndex = random.randint(0,len(usableQuestions) - 1) 
    randQuestion = usableQuestions[randomIndex] #Picks random question 
    correctAnswer = allAnswers[randomIndex] 


    newQuestionPath = mainFolderPath + randQuestion 
    usableQuestions.pop(randomIndex) 
    allAnswers.pop(randomIndex) 

    return newQuestionPath 

img = ImageTk.PhotoImage(Image.open(picPath)) 
panel = tk.Label(root,image = img) 

panel.pack(side = "bottom",fill = "both",expand = "yes") 
setState(0) 
root.after(10,safety_loop) 
root.mainloop() 
+0

'setState' 함수의'currentState' 변수는 파이썬에 의해 로컬 변수로 간주되므로 함수에'global currentState' _inside_를 추가해야한다고 생각합니다. –

답변

1

의 종류를 배우고과 같이 setState 기능을 전역 변수에 currentState을해야 나와 함께 곰하시기 바랍니다.

def setState(newState): 
    currentState = newState 

다른 기능을 사용할 수있는, setState에서 로컬 변수를 만들었다.

def setState(newState): 
    ## make currentStage and stateStartTime global 
    global currentState, stateStartTime 
    currentState = newState 
    stateStartTime = time.time() 

당신은 또한 global 키워드를 사용해야 나는 일부 모듈이없는 완벽하기 때문에 코드를 테스트 할 수 있습니다 (글로벌 변수를 변경 다른 기능에 전술 표시 -as : 귀하의 setState funnction이 있어야한다)

+0

그래서 그 일을 시도하고 첫 번째 오류를 해결했습니다. 또한 글로벌 변수를 변경하는 다른 함수와 같은 코드를 global 키워드로 변경했습니다. 그러나 지금은 GUI 대신 이미지 대신 검은 색 화면이 표시됩니다. 어디서부터 오류 코드가 나타나지 않을 것이므로 여기에서 어디로 가야할 지 모르겠다. – user2776808

+0

윈도우에서 GUI와 이미지 부분을 테스트했는데'root.wm_attributes ('- type', 'splash')', 나는 그것이 오류를주고 있었기 때문에 주석을 써야했다. (아직 Pi에 대해 시험 할 기회가 없었다.) 동일한 코드를 사용해도 모든 코드를 제거하고 GUI 및 이미지 파트를 그대로두고 테스트 할 수 있습니다. – Khristos