2017-03-20 7 views
1

Ich rufe dieses Skript von einer Tkinter-GUI, die ich gemacht habe, und eine meiner Variablen kann nicht von einer meiner Funktionen aufgerufen werden und ich kann nicht verstehen, warum es passiert?Python-Modul NameError

Ich bekomme eine NameError, die 'framevalues' ist nicht definiert, wenn ich einen Tastendruck, um eine meiner Tag-Funktionen auslösen.

Vielen Dank im Voraus!

import cv2 
import tkinter as tk 
from tkinter.filedialog import askopenfilename 


def main(): 
    framevalues = [] 
    count = 1 
    selectedvideo = askopenfilename() 
    selectedvideostring = str(selectedvideo) 
    cap = cv2.VideoCapture(selectedvideo) 
    length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) 

    while (cap.isOpened()): 
     ret, frame = cap.read() 

     # check if read frame was successful 
     if ret == False: 
       break 
     # show frame first 
     cv2.imshow('frame',frame) 

     # then waitKey 
     frameclick = cv2.waitKey(0) & 0xFF 

     if frameclick == ord('a'): 
      swingTag(cap) 

     elif frameclick == ord('r'): 
      rewindFrames(cap) 

     elif frameclick == ord('s'): 
      stanceTag(cap) 

     elif frameclick == ord('d'): 
      unsureTag(cap) 

     elif frameclick == ord('q'): 
      with open((selectedvideostring + '.txt'), 'w') as textfile: 
       for item in framevalues: 
        textfile.write("{}\n".format(item)) 
      break 

     else: 
      continue 

    cap.release() 
    cv2.destroyAllWindows() 

def stanceTag(cap):  
    framevalues.append('0' + ' ' + '|' + ' ' + str(int(cap.get(1)))) 
    print (str(int(cap.get(1))), '/', length) 
    print(framevalues) 

def swingTag(cap): 
    framevalues.append('1' + ' ' + '|' + ' ' + str(int(cap.get(1)))) 
    print (str(int(cap.get(1))), '/', length) 
    print(framevalues) 

def unsureTag(cap): 
    framevalues.append('-1' + ' ' + '|' + ' ' + str(int(cap.get(1)))) 
    print (str(int(cap.get(1))), '/', length) 
    print(framevalues) 

def rewindFrames(cap): 
    cap.set(1,((int(cap.get(1)) - 2))) 
    print (int(cap.get(1)), '/', length) 
    framevalues.pop() 
    print(framevalues) 






if __name__ == '__main__': 
    # this is called if this code was not imported ... ie it was directly run 
    # if this is called, that means there is no GUI already running, so we need to create a root 
    root = tk.Tk() 
    root.withdraw() 
    main() 

Antwort

3

framevalues ist eine lokale Variable in Ihrem main() definiert und ist somit innerhalb anderer Funktionen nicht sichtbar. Sie können es entweder global machen, d. H. Es vor main() definieren, oder Sie können es von main() an die anderen Funktionen als normaler Funktionsparameter übergeben, z.

+0

Prost du alle, Jungs, das ist das Problem behoben - ich habe meine Variablen in meine main() -Funktion, so dass ich das Skript von einer GUI ohne automatische Ladevorgang die tkinter Dateiauswahl Prompt ausführen konnte. Das Übergeben von Rahmenwerten und Länge an die anderen Funktionen als Parameter hat mein Problem behoben. Danke noch einmal! – KittenMittons

+0

Es gibt einen alternativen Ansatz, bei dem Sie Ihre Funktionsdefinitionen nicht ändern müssen. Sie können den Bereich einfach erweitern, indem Sie das Schlüsselwort ** global ** verwenden. Sehen Sie sich auch meine Antwort an. –

+1

Ich würde vorschlagen, globale Variablen zu verwenden, wann immer es vermieden werden kann. Im Allgemeinen wird es als eine schlechte Praxis angesehen. Der OP-Code ist das perfekte Beispiel, wo wir keine globalen Variablen brauchen. Es als Parameter zu übergeben, macht Sinn, da sofort sichtbar ist, welche Funktion welche Variablen verwendet. –

1

framevalues ist eine Variable local zu main(). Sie müssen framevalues als Argument an alle Ihre Funktionen übergeben, die es benötigen, damit sie darauf zugreifen können.

Bitte lesen Sie weiter über Variable Scoping. Ich schlage vor, die Antwort in Short Description of the Scoping Rules?

1

Wenn Sie eine Variable zuweisen, erstellen Sie diese Variable in der aktuellen Bereich heißt lokal für die aktuelle Funktion.

Also, was Sie tun können, ist framevalues Variable wie global zu definieren. Das wie folgt erreicht werden kann:

ersetzen

framevalues = [] 

mit

global framevalues 
framevalues = [] 

Sie brauchen nicht den Rest des Codes zu ändern und dies wird gut funktionieren.