2017-03-17 17 views
0

Tkinter GUIには、それぞれ別々のスクリプトを実行する3つのボタンがあります。それらのうちの2つはうまくロードされますが、3つ目はNameErrorをスローし、私の名前の1つが定義されていないと言っています。しかし、GUIを介さずにスクリプトを実行すると、正常に動作します。Tkinterボタンを実行しているスクリプトがNameErrorをスローする

これは、GUIコードです:

import sys 
import os 
import tkinter 
import cv2 
from tkinter.filedialog import askopenfilename 
from tkinter import messagebox 
import numpy as np 
import matplotlib.pyplot as plt 

top=tkinter.Tk() 
top.geometry("300x350") 
top.config(background='black') 
top.title('Test') 
top.resizable(height=False, width=False) 

def thresholdCallBack(): 
    exec(open('motionindexthreshold.py').read()) 

def autoremoveCallBack(): 
    exec(open('motionindexgenerator.py').read()) 

def videoTaggingCallBack(): 
    exec(open('stepthrough.py').read()) 

def quitCallBack(): 
    top.destroy() 

M = tkinter.Message(top, text='Test', width=280, background='black', foreground='white', font=('Courier', 28)) 
B = tkinter.Button(top,text="Define Motion Index Threshold",command= thresholdCallBack) 
C = tkinter.Button(top,text="Autoremove Nonmovement Video Segments",command= autoremoveCallBack) 
D = tkinter.Button(top,text="Tag Video Frames",command= videoTaggingCallBack) 
E = tkinter.Button(top,text="Quit", command=quitCallBack) 
B.config(height=5, width=80, background='red') 
C.config(height=5, width=80, background='blue', foreground='white') 
D.config(height=5, width=80, background='yellow') 
E.config(height=5, width=80, background='green') 
M.pack() 
B.pack() 
C.pack() 
D.pack() 
E.pack() 
top.mainloop() 

そして、これはキーの押下が登録されている時にクラッシュするPythonスクリプトです:

import cv2 
import tkinter as tk 
from tkinter.filedialog import askopenfilename 
from tkinter import messagebox 
import numpy as np 
import os 
import matplotlib.pyplot as plt 
import sys 


framevalues = [] 
count = 1 

root = tk.Tk() 
root.withdraw() 

selectedvideo = askopenfilename() 
selectedvideostring = str(selectedvideo) 
cap = cv2.VideoCapture(selectedvideo) 
length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) 


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

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

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

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



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() 

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

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

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

    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() 

誰もがこの問題を解決する方法任意のアイデアを持っていますか?

おかげ

+0

GUIスクリプトでは何かがインポートされていますが、サブスクリプトでは読み込まれません。 NameErrorは、どの名前が見つからないかを示します。修正は、適切なインポートを使用して、execではなくスクリプトを実行することです。 – Novel

答えて

2

あなたは別のPythonスクリプトからコードを実行する必要がある場合は、あなたが他のスクリプトを取得し、他のスクリプトで関数を実行するために、インポートを使用する必要があります。これは、関数の外にプログラムの中核を持っているので、コードに問題があるため、インポートするとすぐに実行されます。理由(および他の理由から)のために、あなたのコードをすべて関数に入れるべきです。 __main__属性をチェックすることで、コードがインポートされたかどうかを検出できます。

コードを再構成してすべてのコードを関数に移動し、それをインポートしてGUIボタンから適切な関数を呼び出します。

これはあなたのGUIのコードがどのように見えるかです:

import tkinter 

import motionindexthreshold 
import motionindexgenerator 
import stepthrough 

def main(): 
    top=tkinter.Tk() 
    top.geometry("300x350") 
    top.config(background='black') 
    top.title('Test') 
    top.resizable(height=False, width=False) 

    M = tkinter.Message(top, text='Test', width=280, background='black', foreground='white', font=('Courier', 28)) 
    B = tkinter.Button(top,text="Define Motion Index Threshold",command=motionindexthreshold.main) 
    C = tkinter.Button(top,text="Autoremove Nonmovement Video Segments",command=motionindexgenerator.main) 
    D = tkinter.Button(top,text="Tag Video Frames",command=stepthrough.main) 
    E = tkinter.Button(top,text="Quit", command=top.destroy) 
    B.config(height=5, width=80, background='red') 
    C.config(height=5, width=80, background='blue', foreground='white') 
    D.config(height=5, width=80, background='yellow') 
    E.config(height=5, width=80, background='green') 
    M.pack() 
    B.pack() 
    C.pack() 
    D.pack() 
    E.pack() 
    top.mainloop() 

if __name__ == '__main__': 
    main() 

そして、これはあなたのモジュールのコードがどのように見えるかです:明らかに、この

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

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

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

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

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


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, framevalues) 

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

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

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

     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() 

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() 

の推測です。これがあなたの問題を解決するかどうかはテストする方法がありませんが、私はそれができると思います。

+1

あなたが変更した内容を説明できるなら、この回答ははるかに良いでしょう。さもなければ、OPはあなたの解決策を行ごとに元のものと比較しなければなりません。 –

+0

ありがとう、これは本当に役立ち、私の問題のほとんどを解決しました。ただ一つの問題です。私の関数を実行するためにキーを押すと、 'framevalues'が定義されていないという名前エラーが発生します。これをどうすれば解決できますか?乾杯 – KittenMittons

+0

ああ私はあなたもあなたの機能にそれを必要と見落としました。ちょうど 'キャップ'のようにそれを渡す。私はそれを示すために私の答えを更新しました。 – Novel

関連する問題