Tkinter按钮执行脚本抛出NameError

时间:2017-03-17 19:17:34

标签: python python-3.x user-interface tkinter

我有一个Tkinter GUI,其中三个按钮分别运行一个单独的脚本。其中两个加载正常,但第三个抛出一个NameError,说我的一个名字没有定义。但是,当我不通过GUI运行脚本时,它运行正常。

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

有没有人有任何想法如何解决这个问题?

由于

1 个答案:

答案 0 :(得分:2)

如果您需要从另一个python脚本运行代码,那么您应该使用导入来获取另一个脚本并在另一个脚本中运行一个函数。这将是您的代码的一个问题,因为您的程序核心在函数之外,因此它会在导入后立即运行。出于这个原因(以及其他原因),您应该将所有代码都放在函数中。您可以通过检查npm install属性来检测代码是否已导入。

我重新构建了代码,将所有代码移动到函数中,然后导入它并从GUI按钮调用相应的函数。

这是您的GUI代码应该是这样的:

__main__

这就是你的模块代码应该是这样的:

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

显然这是猜测;我无法测试这是否解决了你的问题,但我认为它会。